Verwendete Pakete laden und installieren
install.packages("vegan")
install.packages("dpylr")
install.packages("ggplot2")
install.packages("nortest")
install.packages("ggpubr")
install.packages("cowplot")
install.packages("ggsignif")
install.packages("tidyverse")
install.packages("Hmisc")
install.packages("corrplot")
install.packages("PerformanceAnalytics")
install.packages("xts")
install.packages("quadprog")
install.packages("Rmisc")
library("dplyr")
library("vegan")
library("ggplot2")
library("nortest")
library("biomformat")
library("ggpubr")
library("cowplot")
library("ggsignif")
library("reshape2")
library("tidyverse")
library("Hmisc")
library("corrplot")
library("PerformanceAnalytics")
library("xts")
1.SCFA Analyse 1.1 Normalverteilung
SCFA_stool <- read.table("/Users/student05/Downloads/SCFA_stool total SCFA.txt", sep = '\t', comment='',head=T, row.names = 1)
View(SCFA_stool)
SCFA_stool<- add.rownames(SCFA_stool, "SampleID")
SCFA_stool$Time <-factor(SCFA_stool$Time, levels = c("PRE", "POST", "FOLLOWUP"))
SCFA_stool[1,3]<- "PRE"
SCFA_stool[1,4]<- "OU1"
scfa_colnames <- colnames(SCFA_stool[, c(6:10)])
nd.SCFA<- data_frame()
scfa
scfa_colnames[1]
for (i in scfa_colnames) {
fit <- shapiro.test(as.matrix(as.data.frame(lapply(SCFA_stool[,i],
as.numeric))))
p = fit$p.value
nrow = nrow(nd.SCFA)+1
nd.SCFA[nrow, "column"] = i
nd.SCFA[nrow, "p.value"] = round(p, 4)
}
sign.nd_SCFA <- filter(nd.SCFA, p > 0.05)
ggqqplot(SCFA_stool$Acetate, ylab = "Acetate concentration nmol/mg", xlab = "SampleID")
ggqqplot(SCFA_stool$Iso.Butyrate, ylab = "Iso-Butyrate concentration nmol/mg", xlab = "SampleID")
ggqqplot(SCFA_stool$Propionate, ylab = "Propionate concentration nmol/mg", xlab = "SampleID")
ggqqplot(SCFA_stool$Butyrate, ylab = "Butyrate concentration nmol/mg", xlab = "SampleID")
Filtern der SCFA-Daten nach PRE und POST Proben
SCFA_stool_pairs <- filter(SCFA_stool, Proband == "05AP" | Proband == "06WT"
| Proband == "07RW" | Proband == "13BS" | Proband == "17SK"
| Proband == "22WS" | Proband == "25FE" | Proband == "26FB"
| Proband == "28HM" | Proband == "29MK" | Proband == "30HB"
| Proband == "31KE" | Proband == "32FG" | Proband == "36ER"
| Proband == "37SD" | Proband == "38AR" | Proband == "40WA"
| Proband == "41ML" | Proband == "45GL" | Proband == "47OT"
| Proband == "50DM" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
SCFA_stool_pairs_PP <- filter(SCFA_stool_pairs, Time=="PRE" | Time=="POST")
SCFA_stool_pairs_PPFU <- filter(SCFA_stool, Proband == "05AP" | Proband == "13
BS" | Proband == "17SK" | Proband == "22WS" | Proband ==
"40WA" | Proband == "41ML" | Proband == "54SL")
Wilcoxon-Test zwischen den Zeitpunkten der SCFA
PRE und POST
wilcox_SCFA<- data_frame()
for (i in scfa_colnames) {
tmp<- filter(SCFA_stool_pairs_PP[ ,i])
x <- as.matrix(as.data.frame(lapply(tmp[,i], as.numeric)))
y <- SCFA_stool_pairs_PP$Time
tmp_wilcox <- pairwise.wilcox.test(x, y, p.adjust.method = 'BH', paired = TRUE)
p <- tmp_wilcox$p.value
nrow = nrow(wilcox_SCFA)+1
wilcox_SCFA[nrow, "SCFA"] <- i
wilcox_SCFA[nrow, "Mean PRE"] <- round(apply(subset(filter(SCFA_stool_pairs, Time == "PRE")[,i], na.rm = TRUE), 2, mean, na.rm = TRUE), 4)
wilcox_SCFA[nrow, "sd PRE"] <- round(apply(subset(filter(SCFA_stool_pairs,Time == "PRE")[,i], na.rm = TRUE), 2, sd,na.rm = TRUE), 4)
wilcox_SCFA[nrow, "Mean POST"] <-round(apply(subset(filter(SCFA_stool_pairs,Time == "POST")[,i], na.rm = TRUE), 2, mean,na.rm = TRUE), 4)
wilcox_SCFA[nrow, "sd POST"] <- round(apply(subset(filter(SCFA_stool_pairs,Time == "POST")[,i], na.rm = TRUE), 2, sd,na.rm = TRUE), 4)
wilcox_SCFA[nrow, "p.value"] <- round(p, 4) }
Acetate p.value = 0.025 -> signifikanter Unterschied!, mean PRE = 205.3, sd PRE = 148.3, mean POST = 132.58, sd POST = 79 Propionate p=0.136 -> kein signifikanter Unterschied!, mean PRE = 78.4, sd PRE = 62.7, mean POST = 54.3, sd POST = 33.1 Butyrate p-value = 0.346 -> kein signifikanter Unterschied!, mean PRE = 59.2, sd PRE = 41.4, mean POST = 44.5, sd POST = 27 Isobutyrate p-value = 0.571 -> kein signifikanter Unterschied!, mean PRE = 9.39, sd PRE = 4.55, mean POST = 9.17, sd POST = 3.1
Wilcoxon-Test Follow-up
wilcox_SCFA_FU <- data_frame()
for (i in scfa_colnames) {
tmp <- filter(SCFA_stool_pairs_PPFU[,i], !is.na(i))
x <- as.matrix(as.data.frame(lapply(tmp[,i], as.numeric)))
y <- SCFA_stool_pairs_PPFU$Time
tmp_wilcox <- pairwise.wilcox.test(x, y, p.adjust.method = 'BH', paired = TRUE)
p_POST_FU <- tmp_wilcox$p.value[1]
p_PRE_FU <- tmp_wilcox$p.value[2]
p_PRE_POST <- tmp_wilcox$p.value[4]
nrow = nrow(wilcox_SCFA_FU)+1
wilcox_SCFA_FU[nrow, "SCFA"] <- i
wilcox_SCFA_FU[nrow, "Mean FOLLOWUP"] <- round(apply(subset(filter(SCFA_stool_pairs_PPFU, Time == "FOLLOWUP")[,i], na.rm = TRUE),2, mean, na.rm = TRUE), 4)
wilcox_SCFA_FU[nrow, "sd FOLLOWUP"] <- round(apply(subset(filter(SCFA_stool_pairs_PPFU, Time =="FOLLOWUP")[,i], na.rm = TRUE), 2, sd, na.rm = TRUE), 4)
wilcox_SCFA_FU[nrow, "p.value_POST_FU"] <- round(p_POST_FU, 2)
wilcox_SCFA_FU[nrow, "p.value_PRE_FU"] <- round(p_PRE_FU, 2)
wilcox_SCFA_FU[nrow, "p.value_PRE_POST"] <- round(p_PRE_POST, 2)
}
Acetate p.valuePOST/FU = 0.56, p.valuePRE/FU = 0.47, p.valuePRE/POST = 0.47 -> alles kein signifikanter Unterschied! mean FU = 173, sd FU = 43.7 Propionate p.valuePOST/FU = 0.94, p.valuePRE/FU = 0.94, p.valuePRE/POST = 0.94 -> alles kein signifnikanter Unterschied! mean FU = 58.7, sd FU= 10.1 Butyrate p.valuePOST/FU = 0.7, p.valuePRE/FU = 0.7, p.valuePRE/POST = 0.7 -> kein signifikanter Unterschied bei allen! mean FU = 43.5, sd FU = 17.9 Isobutyrate p.valuePOST/FU = 1, p.valuePRE/POST = 1, p.valuePRE/FU = 1 -> bei allen kein signifikanter Unterschied! mean FU = 9.14, sd FU = 2.13
Plotten aller SCFA Alle Zeiten zusammen
SCFA_stool.melt <- melt(SCFA_stool_pairs, id.vars = 'Time', measure.vars = c('Acetate', 'Propionate', 'Butyrate', 'Iso.Butyrate'))
SCFA_stool.melt <- subset(filter(SCFA_stool.melt, !Time == 'FOLLOWUP'))
SCFA_stool.melt <- dplyr::rename(SCFA_stool.melt, SCFA=variable)
SCFA_stool.melt <- dplyr::rename(SCFA_stool.melt, Concentration=value)
pdf("/Users/student05/Documents/fertige Plots/SCFA.alltimes.neu.pdf",width=6, height=10)
ggplot(SCFA_stool.melt,aes(x=SCFA, y=Concentration, fill= SCFA)) +
xlab ('SCFA') + ylab ('Konzentrationen [µmol/g]') +
geom_boxplot(width = .4, lwd=1) + theme_classic()+
scale_fill_manual(labels = c("Acetate", "Propionate", "Butyrate", "Iso-Butyrate"), values = c("seagreen4", "seagreen3", "seagreen2", "seagreen1"))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
dev.off()
Plotten der SCFA je Zeitpunkt
pdf("/Users/student05/Documents/fertige Plots/SCFA.times.pdf",width=6, height=10)
ggplot(SCFA_stool.melt,aes(x=Time, y=Concentration, fill= SCFA)) +
xlab ('Zeitpunkt') + ylab ('Konzentrationen [µmol/g]') +
geom_boxplot(width = 0.8, lwd=1) +
scale_fill_manual(labels = c("Acetate", "Propionate", "Butyrate", "Iso-Butyrate"), values = c("seagreen4", "seagreen3", "seagreen2", "seagreen1"))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text( hjust=1))+
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
dev.off()
Plotten der einzelnen SCFA Acetat
Acetate_stool.melt <- melt(SCFA_stool_pairs, id.vars = 'Time', measure.vars = c('Acetate'))
Acetate_stool.melt <- rename(Acetate_stool.melt, SCFA=variable)
Acetate_stool.melt <- rename(Acetate_stool.melt, Concentration=value)
ggplot(Acetate_stool.melt) +
xlab ('Time Point') + ylab ('Concentration [mg/ml]') +
geom_boxplot(aes(x=Time, y=Concentration, fill=SCFA)) +
scale_fill_manual(labels = c("Acetate"), values = c("tomato")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons = list(c("PRE","POST")))
Boxplot mit je 2 SCFA je Zeitpunkt, linked by Probands
Acetat-Propionat
SCFA_stool_melt_AP <-melt(SCFA_stool_pairs, id.vars = c('Time','Proband'), measure.vars = c('Acetate', 'Propionate'))
SCFA_stool_melt_AP <- rename(SCFA_stool_melt_AP, Concentration=value)
SCFA_stool_melt_AP <- rename(SCFA_stool_melt_AP, SCFA=variable)
ggpaired(SCFA_stool_melt_AP, x='SCFA', y='Concentration', color = 'black', fill= 'SCFA',
palette = c('whitesmoke', 'whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE, label = 'Proband') +
xlab('SCFA') + ylab('Concentration [mg/ml]') +
scale_fill_manual(labels=c("Acetate", "Propionat"), values = c("yellowgreen", "steelblue2"))
Acetat-Butyrat
SCFA_stool_melt_AB <-melt(SCFA_stool_pairs, id.vars = c('Time','Proband'), measure.vars = c('Acetate', 'Butyrate'))
SCFA_stool_melt_AB <- rename(SCFA_stool_melt_AB, Concentration=value)
SCFA_stool_melt_AB <- rename(SCFA_stool_melt_AB, SCFA=variable)
ggpaired(SCFA_stool_melt_AB, x='SCFA', y='Concentration', color = 'black', fill= 'SCFA',
palette = c('whitesmoke', 'whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE, label = 'Proband') +
xlab('SCFA') + ylab('Concentration [mg/ml]') +
scale_fill_manual(labels=c("Acetate", "Butyrate"), values = c("yellowgreen", "coral2"))
Acetat-Isobutyrat
SCFA_stool_melt_AI <-melt(SCFA_stool_pairs, id.vars = c('Time','Proband'), measure.vars = c('Acetate', 'Iso.Butyrate'))
SCFA_stool_melt_AI <- rename(SCFA_stool_melt_AI, Concentration=value)
SCFA_stool_melt_AI <- rename(SCFA_stool_melt_AI, SCFA=variable)
ggpaired(SCFA_stool_melt_AI, x='SCFA', y='Concentration', color = 'black', fill= 'SCFA',
palette = c('whitesmoke', 'whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE, label = 'Proband') +
xlab('SCFA') + ylab('Concentration [mg/ml]')+
scale_fill_manual(labels=c("Acetate", "Iso.Butyrate"), values = c("yellowgreen", "deeppink"))
Propionat-Butyrat
SCFA_stool_melt_PB <-melt(SCFA_stool_pairs, id.vars = c('Time','Proband'), measure.vars = c('Propionate', 'Butyrate'))
SCFA_stool_melt_PB <- rename(SCFA_stool_melt_PB, Concentration=value)
SCFA_stool_melt_PB <- rename(SCFA_stool_melt_PB, SCFA=variable)
ggpaired(SCFA_stool_melt_PB, x='SCFA', y='Concentration', color = 'black', fill= 'SCFA',
palette = c('whitesmoke', 'whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE, label = 'Proband') +
xlab('SCFA') + ylab('Concentration [mg/ml]')+
scale_fill_manual(labels=c("Propionate", "Butyrate"), values = c("steelblue2", "coral2"))
Butyrat-Isobutyrat
SCFA_stool_melt_BI <-melt(SCFA_stool_pairs, id.vars = c('Time','Proband'), measure.vars = c('Butyrate', 'Iso.Butyrate'))
SCFA_stool_melt_BI <- rename(SCFA_stool_melt_BI, Concentration=value)
SCFA_stool_melt_BI <- rename(SCFA_stool_melt_BI, SCFA=variable)
ggpaired(SCFA_stool_melt_BI, x='SCFA', y='Concentration', color = 'black', fill= 'SCFA',
palette = c('whitesmoke', 'whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE, label = 'Proband') +
xlab('SCFA') + ylab('Concentration [mg/ml]')+
scale_fill_manual(labels=c("Butyrate", "Iso.Butyrate"), values = c("coral2", "deeppink"))
Propionat-Isobutyrat
SCFA_stool_melt_PI <-melt(SCFA_stool_pairs, id.vars = c('Time','Proband'), measure.vars = c('Propionate','Iso.Butyrate'))
SCFA_stool_melt_PI <- rename(SCFA_stool_melt_PI, Concentration=value)
SCFA_stool_melt_PI <- rename(SCFA_stool_melt_PI, SCFA=variable)
ggpaired(SCFA_stool_melt_PI, x='SCFA', y='Concentration', color = 'black', fill= 'SCFA',
palette = c('whitesmoke', 'whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE, label = 'Proband') +
xlab('SCFA') + ylab('Concentration [mg/ml]')+
scale_fill_manual(labels=c("Propionate", "Iso.Butyrate"), values = c("steelblue2", "deeppink"))
1.2 Erstellen einer Korrelationsmatrix zum Testen von Korrelationen zwischen den SCFA
SCFA_stool <- read.table("/Users/student05/Downloads/SCFA_stool total SCFA.txt", sep = '\t', comment='',
head=T, row.names = 1)
write.table(SCFA_stool, file ='/Users/student05/Documents/SCFA/SCFA_stool total SCFA.txt',sep ="\t", col.names = TRUE, row.names = FALSE)
View(SCFA_stool)
SCFA_stool<- add_rownames(SCFA_stool, "SampleID")
SCFA_stool$Time <-factor(SCFA_stool$Time, levels = c("PRE", "POST", "FOLLOWUP"))
SCFA_stool_matrix_PRE <- subset(filter(SCFA_stool, Time == "PRE"))[ ,6:10]
SCFA_stool_matrix_POST <- subset(filter(SCFA_stool, Time == "POST"))[ ,6:10]
res.PRE <- cor(SCFA_stool_matrix_PRE)
res.POST <- cor(SCFA_stool_matrix_POST)
Spearman-Korrelation
res2.PRE <- rcorr(as.matrix(SCFA_stool_matrix_PRE), type = "spearman")
res2.POST <- rcorr(as.matrix(SCFA_stool_matrix_POST), type = "spearman")
Korrelationskoeffizient bestimmen
res2.PRE$r
res2.POST$r
SCFA_stool_PRE_CC <- as.matrix((res2.PRE$r))
SCFA_stool_POST_CC <- as.matrix(res2.POST$r)
p-values bestimmen
res2$P
SCFA_stool_PRE_PV <- as.matrix(res2.PRE$P)
SCFA_stool_POST_PV <- as.matrix(res2.POST$P)
flattenCorrMatrix erstellen für PRE und POST
flattenCorrMatrix.PRE <- function(SCFA_stool_PRE_CC, SCFA_stool_PRE_PV) {
ut <- upper.tri(SCFA_stool_PRE_CC)
data.frame(
row = rownames(SCFA_stool_PRE_CC)[row(SCFA_stool_PRE_CC)[ut]],
column = rownames(SCFA_stool_PRE_CC)[col(SCFA_stool_PRE_CC)[ut]],
cor =(SCFA_stool_PRE_CC)[ut],
p = SCFA_stool_PRE_PV[ut]
)
}
flattenCorrMatrix.PRE(res2.PRE$r, res2.PRE$P)
flattenCorrMatrix.POST <- function(SCFA_stool_POST_CC, SCFA_stool_POST_PV) {
ut <- upper.tri(SCFA_stool_POST_CC)
data.frame(
row = rownames(SCFA_stool_POST_CC)[row(SCFA_stool_POST_CC)[ut]],
column = rownames(SCFA_stool_POST_CC)[col(SCFA_stool_POST_CC)[ut]],
cor =(SCFA_stool_POST_CC)[ut],
p = SCFA_stool_POST_PV[ut]
)
}
flattenCorrMatrix.POST(res2.POST$r, res2.POST$P)
Dataframe erstellen
SCFA_PRE_cor.p <- as.data.frame(flattenCorrMatrix.PRE(res2.PRE$r, res2.PRE$P))
SCFA_POST_cor.p <- as.data.frame(flattenCorrMatrix.POST(res2.POST$r, res2.POST$P))
colnames(SCFA_PRE_cor.p) <- c("SCFA", "SCFA", "correlation coefficient", "p-value")
colnames(SCFA_POST_cor.p) <- c("SCFA", "SCFA", "correlation coefficient", "p-value")
Correlogram erstellen (Package corrplot)
corrplot(res.PRE, type = "upper", order = "hclust",
tl.col = "black", tl.srt = 45)
corrplot(res.POST, type = "upper", order = "hclust",
tl.col = "black", tl.srt = 45)
corrplot(res2.PRE$r, type="upper", order="hclust",
p.mat = res2.PRE$P, sig.level = 0.05, insig = "blank")
corrplot(res2.PRE$r, type="upper", order="hclust",
p.mat = res2.PRE$P, sig.level = 0.05, insig = "blank")
Scatter plots erstellen
chart.Correlation(SCFA_stool_matrix_PRE, histogram=TRUE, pch=19)
chart.Correlation(SCFA_stool_matrix_POST, histogram = T, pch = 19)
heatmap erstellen
col<- colorRampPalette(c("blue", "white", "red"))(20)
heatmap(x = res.PRE, col = col, symm = TRUE)
1.3 Korrelationen zwischen SCFA und Ballaststoffaufnahme
SCFA_stool.f <- read.table("/Users/student05/Documents/SCFA/scfa.fibre.txt", sep = '\t', comment='',head=T, row.names = 1)
SCFA_stool.f <- subset(filter(SCFA_stool.f, !Proband == '33MP'))
SCFA_stool.f[1,3]<- "PRE"
SCFA_stool.f$Time <-factor(SCFA_stool.f$Time, levels = c("PRE", "POST"))
Korrelationen zwischen allen SCFA und Ballaststoffaufnahme In Arbeit
pdf("/Users/student05/Documents/fertige Plots/SCFA.Ballaststoffe.pdf",width=8, height=10)
ggscatter(SCFA_stool.f, x='Total.SCFA', y='Fibre', palette = c('tomato', 'yellowgreen'), add = 'reg.line', color = "grey59",fill = "lightgray",conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0, 80),cor.coef.size = 8, xlab= 'Gesamt-SCFA Konzentrationen [µmol/g]', ylab = 'Ballaststoffaufnahme [g]')+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(hjust=1))+
geom_point(color='black', size=2.5)+
theme(legend.position="none")
dev.off()
cortest einzelne SCFA
cor.test(subset(filter(SCFA_stool.f))$Total.SCFA, subset(filter(SCFA_stool.f))$Fibre, method = "spearman", exact = F)
cor.test(subset(filter(SCFA_stool.f))$Acetate, subset(filter(SCFA_stool.f))$Fibre, method = "spearman", exact = F)
cor.test(subset(filter(SCFA_stool.f))$Propionate, subset(filter(SCFA_stool.f))$Fibre, method = "spearman", exact = F)
cor.test(subset(filter(SCFA_stool.f))$Butyrate, subset(filter(SCFA_stool.f))$Fibre, method = "spearman", exact = F)
cor.test(subset(filter(SCFA_stool.f))$Iso.Butyrate, subset(filter(SCFA_stool.f))$Fibre, method = "spearman", exact = F)
p.adjust(c(0.1407,0.1844,0.2612, 0.06335, 0.986 ), method = 'BH', n=5)
Plotten Acetat-Balasststoffaufnahme
ggscatter(SCFA_stool.f, x='Acetate', y='Fibre',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Acetate concentration [nmol/g]', ylab = 'Fiber intake [g]')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
1.4 High und Low Sterolkonvertierungstypen SCFA
Nach Konvertierungstypen filtern und PRE und POST Proben zusammenfuegen
lowconv <- filter(SCFA_stool, Proband == "05AP" | Proband == "33MP"
| Proband == "38AR" | Proband == "40WA" | Proband == "41ML"
| Proband == "47OT" | Proband == "49RJ" | Proband == "50DM")
lowconv['Phenotype'] = 'low converter'
highconv <- filter(SCFA_stool, Proband == "06WT" | Proband == "07RW"
| Proband == "13BS" | Proband == "17SK" | Proband == "22WS"
| Proband == "25FE" | Proband == "26FB" | Proband == "29MK"
| Proband == "30HB" | Proband == "31KE" | Proband == "36ER"
| Proband == "45GL" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
highconv['Phenotype'] = 'high converter'
highconv$Converter.Type <- NULL
lowconv$Converter.Type <- NULL
noconv <- filter(SCFA_stool, Proband == "28HM" | Proband == "32FG"
| Proband == "34WF" | Proband == "35AD" | Proband == "37SD"
| Proband == "39DA" | Proband == "66DG" | Proband == "70PL")
noconv['Phenotype'] = 'not classified'
noconv$Converter.Type <- NULL
convT <- data.frame()
convT <- bind_rows(lowconv, highconv, noconv)
convT_paired <- filter(convT, Proband == "05AP" | Proband == "06WT"
| Proband == "07RW" | Proband == "13BS" | Proband == "17SK"
| Proband == "22WS" | Proband == "25FE" | Proband == "26FB"
| Proband == "28HM" | Proband == "29MK" | Proband == "30HB"
| Proband == "31KE" | Proband == "32FG" | Proband == "36ER"
| Proband == "37SD" | Proband == "38AR" | Proband == "40WA"
| Proband == "41ML" | Proband == "45GL" | Proband == "47OT"
| Proband == "50DM" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
convT_paired_PP <- filter(convT_paired, Time=="PRE" | Time=="POST")
Boxplot SCFA je Sterolkonvertierungstyp
alle SCFA
SCFA_stool.melt.CT <- melt(convT, id.vars = 'Phenotype', measure.vars = c('Acetate', 'Propionate', 'Butyrate', 'Iso.Butyrate'))
SCFA_stool.melt.CT <- rename(SCFA_stool.melt.CT, SCFA=variable)
SCFA_stool.melt.CT <- rename(SCFA_stool.melt.CT, Concentration=value)
ggplot(SCFA_stool.melt.CT,aes(x=Phenotype, y=Concentration, fill= SCFA)) +
xlab ('Converter type') + ylab ('Concentration [mg/ml]') +
geom_boxplot() +
scale_fill_manual(labels = c("Acetate", "Propionate", "Butyrate", "Iso-Butyrate"), values = c("tomato", "yellowgreen", "steelblue2", "orchid2"))
ggplot(subset(filter(convT, !Phenotype == "not classified")), aes(x=Phenotype, y=Acetate)) +
xlab ('Phenotype') + ylab('Acetate Concentration [mg/ml]')+
geom_boxplot(fill = 'whitesmoke', color = 'black')+
geom_dotplot(bonaxis = 'y', stackdir = 'center', dotsize = 0.3, fill= 'grey22')
Acetat
Acetate_stool.melt.CT <- melt(convT_paired_PP, id.vars = c('Phenotype','Time'), measure.vars = c('Acetate'))
Acetate_stool.melt.CT <- rename(Acetate_stool.melt.CT, SCFA=variable)
Acetate_stool.melt.CT <- rename(Acetate_stool.melt.CT, Concentration=value)
ggplot(filter(Acetate_stool.melt.CT, !Time=="FOLLOW-UP" & !Phenotype=="not classified"),aes(x=Time, y=Concentration, fill= SCFA)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [mg/ml]') +
scale_fill_manual(labels=c("Acetate"), values = c("yellowgreen"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))
Propionat
Propionate_stool.melt.CT <- melt(convT_paired_PP, id.vars = c('Phenotype','Time'), measure.vars = c('Propionate'))
Propionate_stool.melt.CT <- rename(Propionate_stool.melt.CT, SCFA=variable)
Propionate_stool.melt.CT <- rename(Propionate_stool.melt.CT, Concentration=value)
ggplot(filter(Propionate_stool.melt.CT, !Time=="FOLLOW-UP" & !Phenotype=="not classified"),aes(x=Time, y=Concentration, fill= SCFA)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [mg/ml]') +
scale_fill_manual(labels=c("Propionat"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))
Butyrat
Butyrate_stool.melt.CT <- melt(convT_paired_PP, id.vars = c('Phenotype','Time'), measure.vars = c('Butyrate'))
Butyrate_stool.melt.CT <- rename(Butyrate_stool.melt.CT, SCFA=variable)
Butyrate_stool.melt.CT <- rename(Butyrate_stool.melt.CT, Concentration=value)
ggplot(filter(Butyrate_stool.melt.CT, !Time=="FOLLOW-UP" & !Phenotype=="not classified"),aes(x=Time, y=Concentration, fill= SCFA)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [mg/ml]') +
scale_fill_manual(labels=c("Butyrate"), values = c("coral2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))
Isobutyrat
Iso.Butyrate_stool.melt.CT <- melt(convT_paired_PP, id.vars = c('Phenotype','Time'), measure.vars = c('Iso.Butyrate'))
Iso.Butyrate_stool.melt.CT <- rename(Iso.Butyrate_stool.melt.CT, SCFA=variable)
Iso.Butyrate_stool.melt.CT <- rename(Iso.Butyrate_stool.melt.CT, Concentration=value)
ggplot(filter(Iso.Butyrate_stool.melt.CT, !Time=="FOLLOW-UP" & !Phenotype=="not classified"),aes(x=Time, y=Concentration, fill= SCFA)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [mg/ml]') +
scale_fill_manual(labels=c("Iso.Butyrate"), values = c("deeppink"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))
Plot p-value zwischen Sterolconverter bei einem Zeitpunkt
ggplot(filter(Acetate_stool.melt.CT, !Phenotype=="not classified"),aes(x=Time, y=Concentration, fill= SCFA)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [mg/ml]') +
scale_fill_manual(labels=c("Acetate"), values = c("yellowgreen"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))
ggplot(filter(Propionate_stool.melt.CT, !Phenotype=="not classified"),aes(x=Phenotype, y=Concentration, fill= SCFA)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [mg/ml]') +
scale_fill_manual(labels=c("Propionate"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))
ggplot(filter(Butyrate_stool.melt.CT, !Phenotype=="not classified"),aes(x=Phenotype, y=Concentration, fill= SCFA)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [mg/ml]') +
scale_fill_manual(labels=c("Butyrate"), values = c("coral2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))
ggplot(filter(Iso.Butyrate_stool.melt.CT, !Phenotype=="not classified"),aes(x=Phenotype, y=Concentration, fill= SCFA)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [mg/ml]') +
scale_fill_manual(labels=c("Iso.Butyrate"), values = c("deeppink"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))
1.5 Diversitaetsanalysen SCFA- Shannon/Simpson Daten Laden
SCFA_stool <- read.table("/Users/student05/Downloads/SCFA_stool total SCFA.txt", sep = '\t', comment='',
head=T, row.names = 1)
map_alphadiv <- read.table("/Users/student05/Documents/txt dateien r/means_alpha_div.txt", sep = '\t', comment='',head = TRUE, row.names = 1)
Filtern fuer PRE und POST Proben
SCFA_stool$Time <-factor(SCFA_stool$Time, levels = c("PRE", "POST", "FOLLOW-UP"))
SCFA_stool[1,4]<- "OU1"
SCFA_stool_pairs <- filter(SCFA_stool, Proband == "05AP" | Proband == "06WT"
| Proband == "07RW" | Proband == "13BS" | Proband == "17SK"
| Proband == "22WS" | Proband == "25FE" | Proband == "26FB"
| Proband == "28HM" | Proband == "29MK" | Proband == "30HB"
| Proband == "32FG" | Proband == "36ER" | Proband == "35AD"
| Proband == "37SD" | Proband == "38AR" | Proband == "40WA"
| Proband == "41ML" | Proband == "47OT"
| Proband == "50DM" | Proband == "53BD" | Proband == "57MT" | Proband == "69HL")
write.table(SCFA_stool_pairs, file = '/Users/student05/Documents/SCFA/SCFA analyse/OTU SCFA analyse/SCFA_stool.pairs Shannon Simpson.txt', sep ="\t", col.names= TRUE,row.names = FALSE)
SCFA_stool_pairs_PP <- filter(SCFA_stool_pairs, Time=="PRE" | Time=="POST")
write.table(SCFA_stool_pairs_PP, file = '/Users/student05/Documents/SCFA/SCFA analyse/OTU SCFA analyse/SCFA_stool.pairs.PP Shannon Simpson.txt', sep ="\t", col.names= TRUE,row.names = FALSE)
Shannon und Simpson einfuegen in SCFA Datensatz
common.ids.St <- intersect(rownames(SCFA_stool), rownames(map_alphadiv))
common.ids.St <- intersect(row.names(SCFA_stool), row.names(map_alphadiv))
SCFA_stool <- SCFA_stool[common.ids.St,]
map_alphadiv <- map_alphadiv[common.ids.St,]
SCFA_stool$Shannon <- map_alphadiv$Shannon
SCFA_stool$Simpson <- map_alphadiv$Simpson
Korrelationsanalysen zwischen SCFA und Shannon Erstellen von Matrix und Loop, filtern fuer Signifikanz
corr_colnames_SCFA <-colnames(SCFA_stool[,6:9])
corr_spearman_Shannon_SCFA <- data.frame()
for( i in unique(corr_colnames_SCFA)) {
tmp <- filter(SCFA_stool, !is.na(i))
x = as.matrix(as.data.frame(lapply(tmp[,i], as.numeric)))
y = t(as.matrix(tmp$Shannon) )
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "PRE"))[,i],as.numeric)))
w = t(as.matrix(subset(filter(tmp, Time == "PRE"))$Shannon))
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "POST"))[,i],as.numeric)))
s = t(as.matrix(subset(filter(tmp, Time == "POST"))$Shannon))
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
a = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "FOLLOW-UP"))[,i],as.numeric)))
b = t(as.matrix(subset(filter(tmp, Time == "FOLLOW-UP"))$Shannon))
tmp_corr_spearman_FU <- cor.test(a, b, method="spearman")
rho_FU = tmp_corr_spearman_FU$estimate
p_FU = tmp_corr_spearman_FU$p.value
nrow = nrow(corr_spearman_Shannon_SCFA)+1
corr_spearman_Shannon_SCFA[nrow,"Div"] = "Shannon"
corr_spearman_Shannon_SCFA[nrow, "column"] = i
corr_spearman_Shannon_SCFA[nrow, "rho"] = rho
corr_spearman_Shannon_SCFA[nrow, "p.value"] = p
corr_spearman_Shannon_SCFA[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Shannon_SCFA[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Shannon_SCFA[nrow, "rho_POST"] = rho_POST
corr_spearman_Shannon_SCFA[nrow, "p.value_POST"] = p_POST
corr_spearman_Shannon_SCFA[nrow, "rho_FU"] = rho_FU
corr_spearman_Shannon_SCFA[nrow, "p.value_FU"] = p_FU
}
corr_spearman_Shannon_SCFA$p.adjusted <- p.adjust(corr_spearman_Shannon_SCFA$p.value, method = "BH", n = 5)
corr_spearman_Shannon_SCFA$p.adjusted_PRE <-p.adjust(corr_spearman_Shannon_SCFA$p.value_PRE, method = "BH", n = 5)
corr_spearman_Shannon_SCFA$p.adjusted_POST <- p.adjust(corr_spearman_Shannon_SCFA$p.value_POST, method = "BH", n = 5)
corr_spearman_Shannon_SCFA$p.adjusted_FU <- p.adjust(corr_spearman_Shannon_SCFA$p.value_FU, method = "BH", n = 5)
corr_sig_Shannon_SCFA <- filter(corr_spearman_Shannon_SCFA, p.adjusted < 0.05 | p.adjusted_PRE < 0.5 | p.adjusted_POST < 0.5 | p.adjusted_FU < 0.5)
write.table(corr_sig_Shannon_SCFA, file = '/Users/student05/Documents/SCFA/SCFA analyse/SCFA Tabelle/SCFA.Shannon.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
-> no SCFA has signficicant p-value Acetate has the best p-value with 0.06 < 0.05
Plot Korrelation Acetat/Total scfa und Shannon
ggplot(SCFA_stool, aes(x=Acetate, y=Shannon)) + geom_point(aes(color=Time)) +
scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [mg/ml]') +
ylab('Shannon-Index')
ggplot(SCFA_stool, aes(x=Total.SCFA, y=Shannon)) + geom_point(aes(color=Time)) +
scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total SCFA Concentration [mg/ml]') +
ylab('Shannon-Index')
SCFA_stool <- subset(filter(SCFA_stool, !Time== 'FOLLOW-UP'))
ggscatter(SCFA_stool_pairs_PP, x='Acetate', y='Shannon', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Acetate Concentration [mg/ml]', ylab = 'Shannon-Index') +
facet_wrap(~Time, scales = "free_x")+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(SCFA_stool, x='Total.SCFA', y='Shannon', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(0, 7),xlab= 'Total SCFA Concentration [µmol/g DW]', ylab = 'Shannon-Index')+
facet_wrap(~Time, scales = "free_x")+
theme(legend.position="none")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))
Korrelationsanalysen zwischen SCFA und Simpson Erstellen von Matrix und Loop, filtern fuer Signifikanz
corr_spearman_Simpson_SCFA <- data.frame()
for( i in unique(corr_colnames_SCFA)) {
tmp <- filter(SCFA_stool, !is.na(i))
x = as.matrix(as.data.frame(lapply(tmp[,i], as.numeric)))
y = t(as.matrix(tmp$Simpson))
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "PRE"))[,i],as.numeric)))
w = t(as.matrix (subset(filter(tmp, Time == "PRE"))$Simpson))
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "POST"))[,i],as.numeric)))
s = t(as.matrix(subset(filter(tmp, Time == "POST"))$Simpson))
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
a = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "FOLLOW-UP"))[,i],as.numeric)))
b = t(as.matrix(subset(filter(tmp, Time == "FOLLOW-UP"))$Simpson))
tmp_corr_spearman_FU <- cor.test(a, b, method="spearman")
rho_FU = tmp_corr_spearman_FU$estimate
p_FU = tmp_corr_spearman_FU$p.value
nrow = nrow(corr_spearman_Simpson_SCFA)+1
corr_spearman_Simpson_SCFA[nrow,"Div"] = "Simpson"
corr_spearman_Simpson_SCFA[nrow, "column"] = i
corr_spearman_Simpson_SCFA[nrow, "rho"] = rho
corr_spearman_Simpson_SCFA[nrow, "p.value"] = p
corr_spearman_Simpson_SCFA[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Simpson_SCFA[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Simpson_SCFA[nrow, "rho_POST"] = rho_POST
corr_spearman_Simpson_SCFA[nrow, "p.value_POST"] = p_POST
corr_spearman_Simpson_SCFA[nrow, "rho_FU"] = rho_FU
corr_spearman_Simpson_SCFA[nrow, "p.value_FU"] = p_FU
}
corr_spearman_Simpson_SCFA$p.adjusted <- p.adjust(corr_spearman_Simpson_SCFA$p.value,method = "BH", n = 5)
corr_spearman_Simpson_SCFA$p.adjusted_PRE <-p.adjust(corr_spearman_Simpson_SCFA$p.value_PRE, method = "BH", n = 5)
corr_spearman_Simpson_SCFA$p.adjusted_POST <- p.adjust(corr_spearman_Simpson_SCFA$p.value_POST, method = "BH", n = 5)
corr_spearman_Simpson_SCFA$p.adjusted_FU <- p.adjust(corr_spearman_Simpson_SCFA$p.value_FU, method = "BH", n = 5)
corr_sig_Simpson_SCFA <- filter(corr_spearman_Simpson_SCFA, p.adjusted < 0.05 | p.adjusted_PRE < 0.5 | p.adjusted_POST < 0.5 | p.adjusted_FU < 0.5)
write.table(corr_sig_Simpson_SCFA, file = '/Users/student05/Documents/SCFA/SCFA analyse/SCFA Tabelle/SCFA.Simpson.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
no metadata has significant p-value Propionat has lowest p-value 0.10 > 0.05
Plot metadata fuer Propionate/Total scfa und Simpson
ggplot(SCFA_stool, aes(x=Propionate, y=Simpson)) + geom_point(aes(color=Time))+
scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Propionate Concentration [mg/ml]') +
ylab('Simpson-Index')
ggplot(SCFA_stool, aes(x=Total.SCFA, y=Simpson)) + geom_point(aes(color=Time))+
scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total SCFA Concentration [mg/ml]') +
ylab('Simpson-Index')
ggscatter(SCFA_stool, x='Propionate', y='Simpson', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'),
add = 'reg.line', conf.int = TRUE, cor.coef= TRUE, cor.coef.coord = c(0,0.998),
cor.method = 'spearman', xlab= 'Propionate Concentration [mg/ml]', ylab = 'Simpson-Index') +
facet_wrap(~Time)
ggscatter(SCFA_stool, x='Total.SCFA', y='Simpson', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'),
add = 'reg.line', conf.int = TRUE, cor.coef= TRUE, cor.coef.coord = c(0,0.998),
cor.method = 'spearman', xlab= 'Total SCFA Concentration [mg/ml]', ylab = 'Simpson-Index') +
facet_wrap(~Time)
ggscatter(SCFA_stool, x='Total.SCFA', y='Simpson',
add = 'reg.line', conf.int = TRUE, cor.coef= TRUE, cor.coef.coord = c(0,0.998),
cor.method = 'spearman', xlab= 'Total SCFA Concentration [µmol/g]', ylab = 'Simpson-Index')
Daten sichern
corr_aphadiv_SCFA <- data_frame()
corr_aphadiv_SCFA <-bind_rows(corr_spearman_Shannon_SCFA,corr_spearman_Simpson_SCFA)
write.table(corr_aphadiv_SCFA, file = "/Users/student05/Documents/SCFA/SCFA analyse/OTU SCFA analyse/corr_alphadiv_SCFA.txt", sep= "\t", col.names = TRUE, row.names = FALSE)
Shannon and Simpson-Index je Time Point und “high concentration” Probands
SCFA_stool_con <- read.table("/Users/student05/Documents/SCFA/SCFA Tabelle Phenotypen.txt", sep = '\t', comment='',head=T, row.names = 1)
common.ids.St <- intersect(rownames(SCFA_stool_con), rownames(map_alphadiv))
common.ids.St <- intersect(row.names(SCFA_stool_con), row.names(map_alphadiv))
SCFA_stool_con <- SCFA_stool_con[common.ids.St,]
map_alphadiv <- map_alphadiv[common.ids.St,]
Erstellen einer Liste fuer comparisons in boxplots
comparison_con <- list(c("high concentrations", "normal concentrations"))
Wilcoxon Test zwischen Phaenotypen und Shannon + Boxplot
pairwise.wilcox.test(subset(filter(SCFA_stool_con, Time == "PRE"))$Shannon, subset(filter(SCFA_stool_con, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
ggplot(subset(filter(SCFA_stool_con)), aes(x=Phenotype, y=Shannon)) + xlab('Phenotype') + ylab('Shannon-Index')+
geom_boxplot(fill ='whitesmoke', color = 'black') +
geom_dotplot(binaxis = ' y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))
Wilcoxon test zwischen Phaenotypen und Simpson + Boxplot
pairwise.wilcox.test(subset(filter(SCFA_stool_con, Time == "PRE"))$Simpson, subset(filter(SCFA_stool_con, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
ggplot(subset(filter(SCFA_stool_con)), aes(x=Phenotype, y=Simpson)) + xlab('Phenotype') + ylab('Simpson-Index')+
geom_boxplot(fill ='whitesmoke', color = 'black') +
geom_dotplot(binaxis = ' y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(method = "wilcox.test",comparisons = comparison_con, paired = FALSE, aes(label = ..p.signif..))
1.6 Relative Abundance SCFA-Analyse Laden, filtern fuer high abundant taxa und sichern der Metadaten
L6_rarefied <- read.table("/Users/student05/Documents/Mappingfile_16SrRNA_BC22_L6.txt", sep= '\t', comment='', head=T)
L6_rarefied <- filter(L6_rarefied, Bodysite == "Stool")
row.names(L6_rarefied) <- L6_rarefied$X.SampleID
L6_rarefied <- L6_rarefied[,-c(1:18)]
L6_taxa <- L6_rarefied[, colSums(L6_rarefied > 0.01) > 10]
L6_taxa <- L6_taxa %>% select(-starts_with("Unassigned"))
L6_taxa<- sweep(L6_taxa, 1, rowSums(L6_taxa),'/')
map_KD <- read.table("/Users/student05/Documents/Mappingfile_16SrRNA_BC22.txt", sep ='\t', comment='', head=T,
row.names = 1)
L6_taxa <- rownames_to_column(L6_taxa, "SampleID")
map_KD <- rownames_to_column(map_KD, "SampleID")
L6_metadata_taxa <- merge(map_KD, L6_taxa, by.x=c("SampleID"), by.y=c("SampleID"))
L6_metadata_taxa <- L6_metadata_taxa[,-c(2,3,10:15)]
L6_metadata_taxa <- L6_metadata_taxa[,-c(9)]
write.table(L6_metadata_taxa, file = '/Users/student05/Documents/relative abundance/L6_metadata_taxa_strict_stool.txt', sep = "\t", col.names = TRUE,row.names = FALSE)
Filtern des Datensatzes mit der realtive abundance nach den Zeitpunkten, Bestimmung der Means je Zeitpunkt Zusammenfuegen der Datensätze
relab <- read.table("/Users/student05/Documents/relative abundance/L6_metadata_taxa_strict_stool.txt", sep = '\t', comment='', head=T)
relab_PRE <- filter(relab, Time == "PRE")
relab_POST <- filter(relab, Time == "POST")
relab_FU <- filter(relab, Time == "FOLLOW-UP")
relab_means_PRE <- aggregate(relab_PRE[, 10:90], list(relab_PRE$Proband), mean)
relab_means_PRE['Time'] = 'PRE'
relab_means_PRE <- rename(relab_means_PRE, Proband=Group.1)
relab_means_POST <- aggregate(relab_POST[, 10:90], list(relab_POST$Proband), mean)
relab_means_POST['Time'] = 'POST'
relab_means_POST <- rename(relab_means_POST, Proband=Group.1)
relab_means_FU <- aggregate(relab_FU[, 10:90], list(relab_FU$Proband), mean)
relab_means_FU['Time'] = 'FOLLOW-UP'
relab_means_FU <- rename(relab_means_FU, Proband=Group.1)
relab_means <- data_frame()
relab_means <- bind_rows(relab_means_PRE, relab_means_POST, relab_means_FU)
relab_means <- relab_means[, c(1, 83, 2:82)]
ncol(relab_means)
write.table(relab_means, file = '/Users/student05/Documents/relative abundance/relab_means_per_timepoint.txt',sep = "\t", col.names = TRUE, row.names = FALSE)
Umbenennen der Spalten
relab_means <- read.table('/Users/student05/Documents/relative abundance/relab_means_per_timepoint.txt', sep ='\t', comment='', head=T)
relab_means_melt <- melt(relab_means, id=c('Proband', 'Time'))
relab_means_melt <- rename(relab_means_melt, Taxa=variable)
relab_means_melt <- rename(relab_means_melt, Relative_Abundance=value)
Subset phylum und genus level, sichern der Daten
relab_phylum <- subset(relab_means_melt, !grepl("g__|f__|o__|c__", relab_means_melt$Taxa))
relab_phylum <- subset(relab_phylum, !grepl("k__Archaea", relab_phylum$Taxa))
relab_phylum$Time <- factor(relab_phylum$Time, levels=c('PRE','POST','FOLLOW-UP'))
relab_phylum_spread <- spread(relab_phylum, Taxa, Relative_Abundance, sep = NULL)
relab_genus <- subset(relab_means_melt, grepl("g__", relab_means_melt$Taxa))
relab_genus <- subset(relab_genus, !grepl("k__Archaea", relab_genus$Taxa))
relab_genus$Time <- factor(relab_genus$Time, levels = c('PRE','POST','FOLLOW-UP'))
relab_genus_spread <- spread(relab_genus, Taxa, Relative_Abundance, sep = NULL)
write.table(relab_phylum_spread, file = '/Users/student05/Documents/relative abundance/relab_phylum.txt', sep= "\t", col.names = TRUE, row.names = FALSE)
write.table(relab_genus_spread, file = '/Users/student05/Documents/relative abundance/relab_genus.txt', sep ="\t", col.names = TRUE, row.names = FALSE)
Testen der Taxa auf Normalverteilung, Phylum und Genus Anschließendes Filtern nach Normalverteilung
test_normdist_phylum <- data.frame()
phylum_colnames <- colnames(relab_phylum_spread[, c(3:8)])
for (i in phylum_colnames) {
fit <- shapiro.test(relab_phylum_spread[,i])
p = fit$p.value
nrow = nrow(test_normdist_phylum)+1
test_normdist_phylum[nrow, "p.value"] = p
test_normdist_phylum[nrow, "column"] = i
}
test_normdist_genus <- data_frame()
genus_colnames <-colnames(relab_genus_spread[, c(3:31)])
for (i in genus_colnames) {
fit <- shapiro.test(relab_genus_spread[,i])
p = fit$p.value
nrow = nrow(test_normdist_genus)+1
test_normdist_genus[nrow, "p.value"] = p
test_normdist_genus[nrow, "column"] = i
}
normdist_phylum <- filter(test_normdist_phylum, p.value > 0.05)
normdist_genus <- filter(test_normdist_genus, p.value > 0.05)
-> nur Bacteroidetes, Bacteroides, Dorea, Blautia, Faecalibacterium normalverteilt
Korrelationsanalysen mit SCFA
Synchonisieren der Metadaten
relab_phylum_ID <- relab_phylum_spread
relab_phylum_ID <- mutate(relab_phylum_ID, SampleID = paste(Proband, Time,sep="."))
row.names(relab_phylum_ID) <- relab_phylum_ID$SampleID
relab_genus_ID <- relab_genus_spread
relab_genus_ID <- mutate(relab_genus_ID, SampleID = paste(Proband, Time, sep ="."))
row.names(relab_genus_ID) <- relab_genus_ID$SampleID
SCFA_stool <- read.table("/Users/student05/Downloads/SCFA_stool total SCFA.txt", sep = '\t', comment='',head=T, row.names = 1)
View(SCFA_stool)
SCFA_stool<- add.rownames(SCFA_stool, "SampleID")
SCFA_stool$Time <-factor(SCFA_stool$Time, levels = c("PRE", "POST", "FOLLOWUP"))
SCFA_stool[1,3]<- "PRE"
SCFA_stool[1,4]<- "OU1"
SCFA_stool <- mutate(SCFA_stool, SampleID1 = paste(Proband, Time, sep = "."))
row.names(SCFA_stool) <- SCFA_stool$SampleID1
common.ids.relab <- intersect(rownames(SCFA_stool), rownames(relab_phylum_ID))
SCFA_stool <- SCFA_stool[common.ids.relab,]
relab_phylum_ID <- relab_phylum_ID[common.ids.relab,]
relab_genus_ID <- relab_genus_ID[common.ids.relab,]
write.table(SCFA_stool, file = '/Users/student05/Documents/SCFA/SCFA_stool_total.txt', sep= "\t", col.names = TRUE, row.names = FALSE)
Erstellen einer Matrix zum testen der gewuenschten Daten, hinzufuegen von einem Pseudocount 0.00001 und log-Transformation
phylum_colnames <- colnames(relab_phylum_spread[, c(3:8)])
relab_phylum_ID_log <- relab_phylum_ID[,c(3:8)] + 0.1
relab_phylum_ID_log <- log10(relab_phylum_ID_log)
phylum_SCFA <- cbind(relab_phylum_ID_log, SCFA_stool[, c(1, 3:5, 7:11)])
phylum_SCFA$Time <- factor(phylum_SCFA$Time, levels = c("PRE", "POST"))
Loop Korrelationsanalyse Acetat und Phylum-level
corr_map_phylum_Ac <- filter(phylum_SCFA, !is.na(Acetate))
corr_spearman_Phylum_Ac <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_Ac, !is.na(i))
y = tmp[,i]
x = tmp$Acetate
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Acetate
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Acetate
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_Ac)+1
corr_spearman_Phylum_Ac[nrow,"SCFA"] <- "Acetate"
corr_spearman_Phylum_Ac[nrow, "Phylum"] = i
corr_spearman_Phylum_Ac[nrow, "p.value"] = p
corr_spearman_Phylum_Ac[nrow, "rho"] = rho
corr_spearman_Phylum_Ac[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_Ac[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_Ac[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_Ac[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_Ac$p.adjusted <- p.adjust(corr_spearman_Phylum_Ac$p.value, method = "BH", n = 35)
corr_spearman_Phylum_Ac$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_Ac$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_Ac$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_Ac$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_Ac <- filter(corr_spearman_Phylum_Ac, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_Ac, file = '/Users/student05/Documents/SCFA/SCFA analyse/SCFA Tabelle/Phylum.Ac.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von Acetat und phylum-level
phylum_SCFA$Time <- factor(phylum_SCFA$Time, levels = c("PRE", "POST"))
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Firmicutes, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Actinobacteria, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Bacteroidetes, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [µmol/g]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time, scales = "free_x")
ggscatter(phylum_SCFA, x='Acetate', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0, -0.8), xlab= 'Acetate Concentration [µmol/g DW]', ylab = 'log10 (Relative Abundance p__Bacteroidetes')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_SCFA, x='Acetate', y='k__Bacteria.p__Bacteroidetes', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0, -0.8), xlab= 'Acetate Concentration [µmol/g DW]', ylab = 'log10 (Relative Abundance p__Bacteroidetes')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Proteobacteria, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Tenericutes, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Verrucomicrobia, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [µmol/g]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)
ggscatter(phylum_SCFA, x='Acetate', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0, -0.8), xlab= 'Acetate Concentration [µmol/g DW]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_SCFA, x='Acetate', y='k__Bacteria.p__Verrucomicrobia', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0, -0.8), xlab= 'Acetate Concentration [µmol/g DW]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
Loop Korrelationsanalyse Propionat und Phylum-level
corr_map_phylum_Pr <- filter(phylum_SCFA, !is.na(Propionate))
corr_spearman_Phylum_Pr <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_Pr, !is.na(i))
y = tmp[,i]
x = tmp$Propionate
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Propionate
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Propionate
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_Pr)+1
corr_spearman_Phylum_Pr[nrow,"SCFA"] <- "Propionate"
corr_spearman_Phylum_Pr[nrow, "Phylum"] = i
corr_spearman_Phylum_Pr[nrow, "p.value"] = p
corr_spearman_Phylum_Pr[nrow, "rho"] = rho
corr_spearman_Phylum_Pr[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_Pr[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_Pr[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_Pr[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_Pr$p.adjusted <- p.adjust(corr_spearman_Phylum_Pr$p.value, method = "BH", n = 35)
corr_spearman_Phylum_Pr$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_Pr$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_Pr$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_Pr$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_Pr <- filter(corr_spearman_Phylum_Pr, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_Pr, file = '/Users/student05/Documents/SCFA/SCFA analyse/SCFA Tabelle/Phylum.Pr.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten Propionat und phylum-level
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Firmicutes, x=Propionate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Propionate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Actinobacteria, x=Propionate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Propionate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Bacteroidetes, x=Propionate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Propionate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Proteobacteria, x=Propionate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Propionate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Tenericutes, x=Propionate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Propionate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Verrucomicrobia, x=Propionate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Propionate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)
Loop Butyrat und Phylum-level
corr_map_phylum_Bu <- filter(phylum_SCFA, !is.na(Butyrate))
corr_spearman_Phylum_Bu <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_Bu, !is.na(i))
y = tmp[,i]
x = tmp$Butyrate
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Butyrate
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Butyrate
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_Bu)+1
corr_spearman_Phylum_Bu[nrow,"SCFA"] <- "Butyrate"
corr_spearman_Phylum_Bu[nrow, "Phylum"] = i
corr_spearman_Phylum_Bu[nrow, "p.value"] = p
corr_spearman_Phylum_Bu[nrow, "rho"] = rho
corr_spearman_Phylum_Bu[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_Bu[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_Bu[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_Bu[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_Bu$p.adjusted <- p.adjust(corr_spearman_Phylum_Bu$p.value, method = "BH", n = 35)
corr_spearman_Phylum_Bu$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_Bu$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_Bu$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_Bu$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_Bu <- filter(corr_spearman_Phylum_Bu, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_Bu, file = '/Users/student05/Documents/SCFA/SCFA analyse/SCFA Tabelle/Phylum.Bu.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten Butyrate und phylum-level
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Firmicutes, x=Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Actinobacteria, x=Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Bacteroidetes, x=Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Proteobacteria, x=Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
scale_facet_wrap_discrete(limits = c("PRE", "POST"))
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Tenericutes, x=Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Verrucomicrobia, x=Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)
Loop fuer Isobutyrat und Phylum-level
corr_map_phylum_IB <- filter(phylum_SCFA, !is.na(Iso.Butyrate))
corr_spearman_Phylum_IB <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_IB, !is.na(i))
y = tmp[,i]
x = tmp$Iso.Butyrate
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Iso.Butyrate
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Iso.Butyrate
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_IB)+1
corr_spearman_Phylum_IB[nrow,"SCFA"] <- "Iso.Butyrate"
corr_spearman_Phylum_IB[nrow, "Phylum"] = i
corr_spearman_Phylum_IB[nrow, "p.value"] = p
corr_spearman_Phylum_IB[nrow, "rho"] = rho
corr_spearman_Phylum_IB[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_IB[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_IB[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_IB[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_IB$p.adjusted <- p.adjust(corr_spearman_Phylum_IB$p.value, method = "BH", n = 35)
corr_spearman_Phylum_IB$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_IB$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_IB$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_IB$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_IB <- filter(corr_spearman_Phylum_IB, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_IB, file = '/Users/student05/Documents/SCFA/SCFA analyse/SCFA Tabelle/Phylum.IB.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten Isobutyrat und Phylum-level
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Firmicutes, x=Iso.Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Iso.Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Actinobacteria, x=Iso.Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Iso.Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Bacteroidetes, x=Iso.Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Iso.Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Proteobacteria, x=Iso.Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Iso.Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Tenericutes, x=Iso.Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Iso.Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Verrucomicrobia, x=Iso.Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Iso.Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)
Loop Total SCFA und Phylum-level
corr_map_phylum_TS <- filter(phylum_SCFA, !is.na(Total.SCFA))
corr_spearman_Phylum_TS <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_TS, !is.na(i))
y = tmp[,i]
x = tmp$Total.SCFA
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Total.SCFA
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Total.SCFA
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_TS)+1
corr_spearman_Phylum_TS[nrow,"SCFA"] <- "Total.SCFA"
corr_spearman_Phylum_TS[nrow, "Phylum"] = i
corr_spearman_Phylum_TS[nrow, "p.value"] = p
corr_spearman_Phylum_TS[nrow, "rho"] = rho
corr_spearman_Phylum_TS[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_TS[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_TS[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_TS[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_TS$p.adjusted <- p.adjust(corr_spearman_Phylum_TS$p.value, method = "BH", n = 35)
corr_spearman_Phylum_TS$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_TS$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_TS$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_TS$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_TS <- filter(corr_spearman_Phylum_TS, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_TS, file = '/Users/student05/Documents/SCFA/SCFA analyse/SCFA Tabelle/Phylum.TS.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten Total SCFA und phylum-level
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Firmicutes, x=Total.SCFA)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total.SCFA Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Actinobacteria, x=Total.SCFA)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total.SCFA Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Bacteroidetes, x=Total.SCFA)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total.SCFA Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Proteobacteria, x=Total.SCFA)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total.SCFA Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Tenericutes, x=Total.SCFA)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total.SCFA Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)
ggplot(phylum_SCFA, aes(y=k__Bacteria.p__Verrucomicrobia, x=Total.SCFA)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total.SCFA Concentration [mg/ml]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)
Sichern der Daten
corr_phylum_SCFA <- data_frame()
corr_phylum_SCFA <- bind_rows(corr_spearman_Phylum_Ac,corr_spearman_Phylum_Pr,corr_spearman_Phylum_Bu, corr_spearman_Phylum_IB, corr_spearman_Phylum_TS)
write.table(corr_phylum_SCFA, file = '/Users/student05/Documents/relative abundance/corr_phylum_SCFA_all_PRE_POST.txt',sep = "\t", col.names = TRUE, row.names = FALSE)
Analysen mit Genus-Level
Erstellen und filtern der Matrix, Log-Transformation und hinzufuegen von Pseudocount 0.00001
genus_colnames <- colnames(relab_genus_spread[, c(3:31)])
relab_genus_ID_log <- relab_genus_ID[,c(3:31)] + 0.00001
relab_genus_ID_log <- log10(relab_genus_ID_log)
genus_SCFA <- cbind(relab_genus_ID_log, SCFA_stool[, c(1:10)])
Loop Acetate und Genus-Level
corr_map_genus_Ac <- filter(genus_SCFA, !is.na(Acetate))
corr_spearman_genus_Ac <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_Ac, !is.na(i))
y = tmp[,i]
x = tmp$Acetate
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Acetate
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Acetate
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_Ac)+1
corr_spearman_genus_Ac[nrow,"SCFA"] = "Acetate"
corr_spearman_genus_Ac[nrow, "Genus"] = i
corr_spearman_genus_Ac[nrow, "p.value"] = p
corr_spearman_genus_Ac[nrow, "rho"] = rho
corr_spearman_genus_Ac[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_Ac[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_Ac[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_Ac[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_Ac$p.adjusted <- p.adjust(corr_spearman_genus_Ac$p.value, method = "BH", n = 35)
corr_spearman_genus_Ac$p.adjusted_PRE <- p.adjust(corr_spearman_genus_Ac$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_Ac$p.adjusted_POST <- p.adjust(corr_spearman_genus_Ac$p.value_POST, method = "BH", n = 35)
corr_sig_genus_Ac <- filter(corr_spearman_genus_Ac, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_Ac, file = '/Users/student05/Documents/SCFA/SCFA analyse/SCFA Tabelle/Genus.Ac.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten Acetate und genus-level
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [µmol/g]') +
ylab('log10 (Relative Abundance g__Oscillospira)')+
facet_wrap(~Time)
ggscatter(genus_SCFA, x='Acetate', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(50, -2), xlab= 'Acetate Concentration [µmol/g DW]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_SCFA, x='Acetate', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(50, -2), xlab= 'Acetate Concentration [µmol/g DW]', ylab = 'log10 (Relative Abundance g__Oscillospira')+theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance g__Bifidobacterium)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [nmol/mg DW]') +
ylab('log10 (Relative Abundance g__Collinsella)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance f__Erysipelotrichaceae)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [µmol/g]') +
ylab('log10 (Relative Abundance f__Rikenellaceae)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance g__Faecalibacterium )')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [µmol/g]') +
ylab('log10 (Relative Abundance g__Akkermansia )')+
facet_wrap(~Time)
ggscatter(genus_SCFA, x='Acetate', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(50, -1.1), xlab= 'Acetate Concentration [µmol/g DW]', ylab = 'log10 (Relative Abundance g__Akkermansia')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_SCFA, x='Acetate', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(50, -1.1), xlab= 'Acetate Concentration [µmol/g DW]', ylab = 'log10 (Relative Abundance g__Akkermansia')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance g__Collinsella )')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, x=Acetate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Acetate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance g__Bacteroides )')+
facet_wrap(~Time)
Loop Propionat und Genus-Level
corr_map_genus_Pr <- filter(genus_SCFA, !is.na(Propionate))
corr_spearman_genus_Pr <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_Pr, !is.na(i))
y = tmp[,i]
x = tmp$Propionate
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Propionate
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Propionate
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_Pr)+1
corr_spearman_genus_Pr[nrow,"SCFA"] = "Propionate"
corr_spearman_genus_Pr[nrow, "Genus"] = i
corr_spearman_genus_Pr[nrow, "p.value"] = p
corr_spearman_genus_Pr[nrow, "rho"] = rho
corr_spearman_genus_Pr[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_Pr[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_Pr[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_Pr[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_Pr$p.adjusted <- p.adjust(corr_spearman_genus_Pr$p.value, method = "BH", n = 35)
corr_spearman_genus_Pr$p.adjusted_PRE <- p.adjust(corr_spearman_genus_Pr$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_Pr$p.adjusted_POST <- p.adjust(corr_spearman_genus_Pr$p.value_POST, method = "BH", n = 35)
corr_sig_genus_Pr <- filter(corr_spearman_genus_Pr, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_Pr, file = '/Users/student05/Documents/SCFA/SCFA analyse/SCFA Tabelle/Genus.Pr.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten Propionat und genus-level
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, x=Propionate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Propionate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance g__Oscillospira)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, x=Propionate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Propionate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance f__Rikenellaceae)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__, x=Propionate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Propionate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance f__Erysipelotrichaceae)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, x=Propionate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Propionate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance g__Akkermansia)')+
facet_wrap(~Time)
Loop Butyrat und Genus-Level
corr_map_genus_Bu <- filter(genus_SCFA, !is.na(Butyrate))
corr_spearman_genus_Bu <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_Bu, !is.na(i))
y = tmp[,i]
x = tmp$Butyrate
tmp_corr_spearman <- cor.test(x, y, method="spearman", paied = T)
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Butyrate
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman", paied = T)
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Butyrate
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman", paied = T)
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_Bu)+1
corr_spearman_genus_Bu[nrow,"SCFA"] = "Butyrate"
corr_spearman_genus_Bu[nrow, "Genus"] = i
corr_spearman_genus_Bu[nrow, "p.value"] = p
corr_spearman_genus_Bu[nrow, "rho"] = rho
corr_spearman_genus_Bu[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_Bu[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_Bu[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_Bu[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_Bu$p.adjusted <- p.adjust(corr_spearman_genus_Bu$p.value, method = "BH", n = 35)
corr_spearman_genus_Bu$p.adjusted_PRE <- p.adjust(corr_spearman_genus_Bu$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_Bu$p.adjusted_POST <- p.adjust(corr_spearman_genus_Bu$p.value_POST, method = "BH", n = 35)
corr_sig_genus_Bu <- filter(corr_spearman_genus_Bu, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_Bu, file = '/Users/student05/Documents/SCFA/SCFA analyse/SCFA Tabelle/Genus.Bu.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten Butyrat und genus-level
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, x=Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance g__Oscillospira)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__, x=Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance f__Erysipelotrichaceae)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, x=Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance f__Rikenellaceae)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus., x=Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance g__.Ruminococcus)')+
facet_wrap(~Time)
Loop Isobutyrat und Genus-Level
corr_map_genus_BI <- filter(genus_SCFA, !is.na(Iso.Butyrate))
corr_spearman_genus_BI <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_BI, !is.na(i))
y = tmp[,i]
x = tmp$Iso.Butyrate
tmp_corr_spearman <- cor.test(x, y, method="spearman", paired = T)
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Iso.Butyrate
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman", paired = T)
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Iso.Butyrate
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman", paied = T)
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_BI)+1
corr_spearman_genus_BI[nrow,"SCFA"] = "Iso.Butyrate"
corr_spearman_genus_BI[nrow, "Genus"] = i
corr_spearman_genus_BI[nrow, "p.value"] = p
corr_spearman_genus_BI[nrow, "rho"] = rho
corr_spearman_genus_BI[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_BI[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_BI[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_BI[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_BI$p.adjusted <- p.adjust(corr_spearman_genus_BI$p.value, method = "BH", n = 35)
corr_spearman_genus_BI$p.adjusted_PRE <- p.adjust(corr_spearman_genus_BI$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_BI$p.adjusted_POST <- p.adjust(corr_spearman_genus_BI$p.value_POST, method = "BH", n = 35)
corr_sig_genus_BI <- filter(corr_spearman_genus_BI, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_BI, file = '/Users/student05/Documents/SCFA/SCFA analyse/SCFA Tabelle/Genus.BI.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten Isobutyrat genus-level
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__, x=Iso.Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Iso.Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance f__Coriobacteriaceae)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Proteobacteria.c__Alphaproteobacteria.o__RF32.f__.g__, x=Iso.Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Iso.Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance c__Alphaproteobacteria.o__RF32)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__.g__, x=Iso.Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Iso.Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance c__Clostridia.o__Clostridiales)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus, x=Iso.Butyrate)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Iso.Butyrate Concentration [mg/ml]') +
ylab('log10 (Relative Abundance g__Coprococcus)')+
facet_wrap(~Time)
Loop total SCFA und Genus-Level
corr_map_genus_TS <- filter(genus_SCFA, !is.na(Total.SCFA))
corr_spearman_genus_TS <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_TS, !is.na(i))
y = tmp[,i]
x = tmp$Total.SCFA
tmp_corr_spearman <- cor.test(x, y, method="spearman", paired = T)
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Total.SCFA
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman", paired = T)
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Total.SCFA
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman", paired = T)
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_TS)+1
corr_spearman_genus_TS[nrow,"SCFA"] = "Total.SCFA"
corr_spearman_genus_TS[nrow, "Genus"] = i
corr_spearman_genus_TS[nrow, "p.value"] = p
corr_spearman_genus_TS[nrow, "rho"] = rho
corr_spearman_genus_TS[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_TS[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_TS[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_TS[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_TS$p.adjusted <- p.adjust(corr_spearman_genus_TS$p.value, method = "BH", n = 35)
corr_spearman_genus_TS$p.adjusted_PRE <- p.adjust(corr_spearman_genus_TS$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_TS$p.adjusted_POST <- p.adjust(corr_spearman_genus_TS$p.value_POST, method = "BH", n = 35)
corr_sig_genus_TS <- filter(corr_spearman_genus_TS, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_TS, file = '/Users/student05/Documents/SCFA/SCFA analyse/SCFA Tabelle/Genus.TS.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten total SCFA und genus-level
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, x=Total.SCFA)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total.SCFA [mg/ml]') +
ylab('log10 (Relative Abundance g__Oscillospira)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, x=Total.SCFA)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total.SCFA [mg/ml]') +
ylab('log10 (Relative Abundance f__Rikenellaceae)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__, x=Total.SCFA)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total.SCFA [mg/ml]') +
ylab('log10 (Relative Abundance f__Erysipelotrichaceae)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, x=Total.SCFA)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total.SCFA [mg/ml]') +
ylab('log10 (Relative Abundance g__Bifidobacterium)')+
facet_wrap(~Time)
ggplot(genus_SCFA, aes(y=k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, x=Total.SCFA)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total.SCFA [mg/ml]') +
ylab('log10 (Relative Abundance g__Akkermansia)')+
facet_wrap(~Time)
Daten sichern
corr_genus_SCFA <- data_frame()
corr_genus_SCFA <- bind_rows(corr_spearman_genus_Ac, corr_spearman_genus_Pr,corr_spearman_genus_Bu, corr_spearman_genus_BI, corr_spearman_genus_TS)
write.table(corr_genus_SCFA, file = '/Users/student05/Documents/relative abundance/corr_genus_SCFA_all_PRE_POST.txt', sep = "\t", col.names = TRUE, row.names = FALSE)
corr_genus_SCFA_sig <- data_frame()
corr_genus_SCFA_sig <- bind_rows(corr_sig_genus_Ac, corr_sig_genus_Pr, corr_sig_genus_Bu, corr_sig_genus_BI, corr_sig_genus_TS)
write.table(corr_genus_SCFA_sig, file ='/Users/student05/Documents/relative abundance/corr_genus_SCFA_sig_PRE_POST.txt',sep ="\t", col.names = TRUE, row.names = FALSE)
1.7 Testen von Unterschieden im relativen Vorkommen der Taxa von Probanden mit sehr hohen SCFA-Konzentrationen und normalen SCFA-Konzentrationen
Laden der Metadaten
SCFA_Pt <- read.table("/Users/student05/Documents/SCFA/SCFA Tabelle Phenotypen.txt", sep ='\t',comment='',head=T)
SCFA_Pt[ ,6] <- NULL
Synchonisieren der Metadaten
SCFA_Pt <- mutate(SCFA_Pt, SampleID1 = paste(Proband, Time, sep = "."))
row.names(SCFA_Pt) <- SCFA_Pt$SampleID1
common.ids.relab <- intersect(rownames(SCFA_Pt), rownames(relab_phylum_ID))
SCFA_Pt <- SCFA_Pt[common.ids.relab,]
relab_phylum_ID <- relab_phylum_ID[common.ids.relab,]
relab_genus_ID <- relab_genus_ID[common.ids.relab,]
Matrix erstellen, filtern, hinzufuegen von log und Psedocount
write.table(SCFA_stool, file = '/Users/student05/Documents/SCFA/SCFA_Pt.txt', sep= "\t", col.names = TRUE, row.names = FALSE)
relab_phylum_ID_log <- relab_phylum_ID[,c(3:8)] + 0.1
relab_phylum_ID_log <- log10(relab_phylum_ID_log)
phylum_Pt <- cbind(relab_phylum_ID_log, SCFA_Pt[, c(1, 3:5, 7:11, 14)])
Phylum-Differenzen zwsichen den Phaenotypen
comparison_con <- list(c("low concentrations", "high concentrations"))
pairwise.wilcox.test(subset(filter(phylum_Pt, Time == "PRE"))$k__Bacteria.p__Firmicutes, subset(filter(phylum_Pt, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
ggplot(subset(filter(phylum_Pt)), aes(x=Phenotype,y=k__Bacteria.p__Firmicutes)) + xlab('Phenotype') + ylab('log10 (Relative Abundance p__Firmicutes)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_con)
phylum_Pt$k__Bacteria.p__Actinobacteria
pairwise.wilcox.test(subset(filter(phylum_Pt, Time == "PRE"))$k__Bacteria.p__Actinobacteria, subset(filter(phylum_Pt, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
ggplot(subset(filter(phylum_Pt)), aes(x=Phenotype,y=k__Bacteria.p__Actinobacteria)) + xlab('Phenotype') + ylab('log10 (Relative Abundance p__Actinobacteria)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_con)
phylum_Pt$k__Bacteria.p__Bacteroidetes
pairwise.wilcox.test(subset(filter(phylum_Pt, Time == "PRE"))$k__Bacteria.p__Bacteroidetes, subset(filter(phylum_Pt, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
ggplot(subset(filter(phylum_Pt)), aes(x=Phenotype,y=k__Bacteria.p__Bacteroidetes)) + xlab('Phenotype') + ylab('log10 (Relative Abundance p__Bacteroidetes)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_con)
pairwise.wilcox.test(subset(filter(phylum_Pt, Time == "PRE"))$k__Bacteria.p__Proteobacteria, subset(filter(phylum_Pt, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
ggplot(subset(filter(phylum_Pt)), aes(x=Phenotype,y=k__Bacteria.p__Proteobacteria)) + xlab('Phenotype') + ylab('log10 (Relative Abundance p__Proteobacteria)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_con)
pairwise.wilcox.test(subset(filter(phylum_Pt, Time == "PRE"))$k__Bacteria.p__Tenericutes, subset(filter(phylum_Pt, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
ggplot(subset(filter(phylum_Pt)), aes(x=Phenotype,y=k__Bacteria.p__Tenericutes)) + xlab('Phenotype') + ylab('log10 (Relative Abundance p__Tenericutes)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_con)
pairwise.wilcox.test(subset(filter(phylum_Pt, Time == "PRE"))$k__Bacteria.p__Verrucomicrobia, subset(filter(phylum_Pt, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
ggplot(subset(filter(phylum_Pt)), aes(x=Phenotype,y=k__Bacteria.p__Verrucomicrobia)) + xlab('Phenotype') + ylab('log10 (Relative Abundance p__Verrucomicrobia)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_con)
1.8 Beta-Diversitaet
Laden und filtern der Metadaten
otus_means <- read.table("/Users/student05/Documents/otus_means_stool 2.txt", sep ='\t',comment='',head=T)
setwd("/Users/student05/Documents/SCFA")
map_bdiv <- read.table("/Users/student05/Documents/Mappingfile_16SrRNA_BC22.txt", sep ='\t',comment='',head=T)
map_bdiv <- mutate(map_bdiv, SampleID2 = paste(Proband, Time, sep = "."))
map_bdiv <- filter(map_bdiv, Timepoint == "0U1" | Timepoint =="0U2" | Timepoint =="0U3")
map_bdiv <- filter(map_bdiv, Bodysite == "Stool")
rownames(map_bdiv) <- map_bdiv$SampleID2
Synchonisieren der Daten
otus_relab <- mutate(otus_means, SampleID = paste(Proband, Time, sep = "."))
rownames(otus_relab) <- otus_relab$SampleID
otus_relab <- sweep(otus_relab[, 2:84606], 1, rowSums(otus_relab[, 2:84606]), '/')
dim(otus_relab)
common.ids.relab <- intersect(rownames(map_bdiv), rownames(otus_relab))
map_bdiv <- map_bdiv[common.ids.relab,]
otus_relab <- otus_relab[common.ids.relab,]
dim(otus_relab)
write.table(otus_relab, file = "otus_relab_bc.txt", sep = "\t", col.names = TRUE,row.names = TRUE)
Bray-Curtis Kalkulation
d.bray <-vegdist(otus_relab)
matrix.bray<- as.matrix(d.bray)
write.table(matrix.bray, file = "matrix.bray.txt", sep = "\t", col.names = T, row.names = T)
Erstellen einer Distance-matrix (All functions used are created by Daniel Podlesny and saved in the R Script “modify_distmat.R”. Open the script in R and run all functions. They will then be listed in the Environment. call the function with the distance matrix for this project)
distmat <- clean_distmat(as.data.frame(matrix.bray))
distmat <- distmat_to_long(distmat, rm_diag = TRUE)
distmat_PRE <- filter(distmat, grepl('*.PRE', distmat$row) & grepl('*.PRE', distmat$col))
distmat_POST <- filter(distmat, grepl('*.POST', distmat$row) & grepl('*.POST', distmat$col))
distmat_FU <- filter(distmat, grepl('*.FOLLOW-UP', distmat$row) & grepl('*.FOLLOW-UP', distmat$col))
distmat_PRE['Time'] = 'PRE'
distmat_POST['Time'] = 'POST'
distmat_FU['Time'] = 'FOLLOW-UP'
distmat_PREvsPOST <- data_frame()
distmat_PREvsPOST <- bind_rows(distmat_PRE, distmat_POST)
distmat_PREvsPOST$Time <- factor(distmat_PREvsPOST$Time, levels = c("PRE", "POST"))
distmat_all <- data_frame()
distmat_all <- bind_rows(distmat_PRE, distmat_POST, distmat_FU)
distmat_all$Time <- factor(distmat_all$Time, levels=c("PRE", "POST", "FOLLOW-UP"))
Filtern fuer Proben mit PRE und POST
distmat_PREvsPOST_pairs <- filter(distmat_PREvsPOST, !row == "31KE.POST" & !row =="34WF.PRE" & !row == "45GL.POST" & !row == "49RJ.PRE" &!row == "54SL.POST" & !row == "70PL.PRE" & !row == "74SA.POST")
distmat_PREvsPOST_pairs <- filter(distmat_PREvsPOST_pairs, !col == "31KE.POST" &!col == "34WF.PRE" & !col == "45GL.POST" & !col == "49RJ.PRE" & !col == "54SL.POST" & !col == "70PL.PRE" & !col == "74SA.POST")
Wilcoxon-Test PRE und POST + boxplot
pairwise.wilcox.test(distmat_PREvsPOST_pairs$distance, distmat_PREvsPOST_pairs$Time, p.adjust.method = "BH", paired = TRUE)
pairwise.wilcox.test(distmat_PREvsPOST_pairs$distance, distmat_PREvsPOST_pairs$Time, p.adjust.method = "BH", paired = TRUE)
ggplot(distmat_PREvsPOST_pairs, aes(x=Time, y=distance)) + xlab('Timepoint') + ylab('Bray-Curtis Dissimilarity (baseline per proband)') +
geom_boxplot(fill='whitesmoke', color="black") + geom_dotplot(binaxis='y', stackdir='center', dotsize=0.2) +
ggtitle('Beta-Diversity between probands before and after a 6-week Ketogenic Diet') +
stat_compare_means(comparison = list(c("PRE", "POST")), paired = TRUE, aes(label= ..p.signif..))
Mean und SD für PRE und POST
mean(subset(filter(distmat_PREvsPOST_pairs, Time == "PRE"))$distance)
sd(subset(filter(distmat_PREvsPOST_pairs, Time == "PRE"))$distance)
mean(subset(filter(distmat_PREvsPOST_pairs, Time == "POST"))$distance)
sd(subset(filter(distmat_PREvsPOST_pairs, Time == "POST"))$distance)
- FA-Analyse
2.1 Normalverteilung Metadaten Laden, filtern und sortieren
FA_stool <- read.table("/Users/student05/Documents/fa feces/Fa.feces.2.txt", sep = '\t', comment='',
head=T)
View(FA_stool)
FA_stool$Time <-factor(FA_stool$Time, levels = c("PRE", "POST"))
FA_stool <- FA_stool[-c(58:64),]
FA_stool<- add_rownames(FA_stool, "SampleID1")
FA_stool.r<- add_rownames(FA_stool, "SampleID1")
row.names(FA_stool) <- FA_stool$SampleID
Testen auf Normalverteilung
FA_colnames <- colnames(FA_stool[, c(7:19)])
nd.FA<- data_frame()
for (i in FA_colnames) {
fit <- shapiro.test(as.matrix(as.data.frame(lapply(FA_stool[,i],
as.numeric))))
p = fit$p.value
nrow = nrow(nd.FA)+1
nd.FA[nrow, "column"] = i
nd.FA[nrow, "p.value"] = round(p, 4)
}
sign.nd_FA <- filter(nd.FA, p.value > 0.05)
Plotten der Normalverteilungen
ggqqplot(FA_stool$sat, ylab = "Saturated FA concentration nmol/g", xlab = "SampleID")
ggqqplot(FA_stool$mono.unsat, ylab = "Mono unsaturated concentration [nmol/g]", xlab = "SampleID")
ggqqplot(FA_stool$di.unsat, ylab = "Diunsaturated concentration [nmol/g]", xlab = "SampleID")
ggqqplot(FA_stool$less.14, ylab = " < 14 c-atoms concentration [nmol/g]", xlab = "SampleID")
ggqqplot(FA_stool$c18.19, ylab = "FA with 18-19 c-atoms concentration [nmol/g]", xlab = "SampleID")
ggqqplot(FA_stool$c14.17, ylab = "FA with 14-17 c-atoms concentration [nmol/g]", xlab = "SampleID")
ggqqplot(FA_stool$c20.21, ylab = "FA with 20-21 c-atoms concentration [nmol/g]", xlab = "SampleID")
ggqqplot(FA_stool$c22.24, ylab = "FA with 22-24 c-atoms concentration [nmol/g]", xlab = "SampleID")
ggqqplot(FA_stool$total, ylab = "Total FA concentration [nmol/g]", xlab = "SampleID")
ggqqplot(FA_stool.r$n.3, ylab = "Omega 3 FA concentration [nmol/g]", xlab = "SampleID")
ggqqplot(FA_stool.r$n.6, ylab = "Omega 6 FA concentration [nmol/g]", xlab = "SampleID")
ggqqplot(FA_stool.r$ratio6.3, ylab = "Omega 6/3 ratio [nmol/g]", xlab = "SampleID")
Filtern nach PRE und POST Proben
FA_stool_pairs <- filter(FA_stool, Proband == "05AP" | Proband == "06WT"
| Proband == "07RW" | Proband == "13BS" | Proband == "17SK"
| Proband == "22WS" | Proband == "25FE" | Proband == "26FB"
| Proband == "28HM" | Proband == "29MK" | Proband == "30HB"
| Proband == "31KE" | Proband == "32FG" | Proband == "36ER"
| Proband == "37SD" | Proband == "38AR" | Proband == "40WA"
| Proband == "41ML" | Proband == "45GL" | Proband == "47OT"
| Proband == "50DM" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
FA_stool_pairs_PP <- filter(FA_stool_pairs, Time=="PRE" | Time=="POST")
FA_stool_pairs_PPFU <- filter(FA_stool, Proband == "05AP" | Proband == "13BS" | Proband == "17SK" | Proband == "22WS" | Proband == "40WA" | Proband == "41ML" | Proband == "54SL")
Wilcoxon-Test zwischen den Zeitpunkten PRE und POST Erstellen eines neuen Dataframes
wilcox_FA<- data_frame()
environment(filter)
for (i in FA_colnames) {
tmp <- FA_stool_pairs %>% drop_na(i)
x <- as.matrix(as.data.frame(lapply(tmp[,i], as.numeric)))
y <- FA_stool_pairs$Time
tmp_wilcox <- pairwise.wilcox.test(x, y, p.adjust.method = 'BH', paired = T)
p <- tmp_wilcox$p.value
nrow = nrow(wilcox_FA)+1
wilcox_FA[nrow, "LI"] <- i
wilcox_FA[nrow, "Mean PRE"] <-round(mean(subset(filter(FA_stool_pairs,Time == "PRE")[,i],!is.na(i),na.rm = TRUE), 2, mean, na.rm = TRUE), 4)
wilcox_FA[nrow, "sd PRE"] <-round(sd(c(subset(filter(FA_stool_pairs,Time == "PRE")[,i],!is.na(i),na.rm = TRUE), na.rm = TRUE)), 4)
wilcox_FA[nrow, "Mean POST"] <-round(mean(subset(filter(FA_stool_pairs,Time == "POST")[,i],!is.na(i), na.rm = TRUE), 2, mean, na.rm = TRUE), 4)
wilcox_FA[nrow, "sd POST"] <- round(sd(c(subset(filter(FA_stool_pairs,Time == "POST")[,i],!is.na(i), na.rm = TRUE),na.rm = TRUE)), 4)
wilcox_FA[nrow, "p.value"] <- round(p, 4) }
write.table(wilcox_FA, file = '/Users/student05/Documents/fa feces/fa tabellen/FA.pre.post.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Zeitpunkte zusammen
wilcox_FA1<- data_frame()
for (i in FA_colnames) {
tmp <- FA_stool_pairs %>% drop_na(i)
x <- as.matrix(as.data.frame(lapply(tmp[,i], as.numeric)))
y <- FA_stool_pairs$Time
tmp_wilcox <- pairwise.wilcox.test(x, y, p.adjust.method = 'BH', paired = T)
p <- tmp_wilcox$p.value
nrow = nrow(wilcox_FA1)+1
wilcox_FA1[nrow, "LI"] <- i
wilcox_FA1[nrow, "Mean"] <-round(mean(subset(filter(FA_stool_pairs)[,i],!is.na(i),na.rm = TRUE), 2, mean, na.rm = TRUE), 4)
wilcox_FA1[nrow, "sd"] <-round(sd(c(subset(filter(FA_stool_pairs)[,i],!is.na(i),na.rm = TRUE), na.rm = TRUE)), 4)
wilcox_FA1[nrow, "p.value"] <- round(p, 4) }
write.table(wilcox_FA1, file = '/Users/student05/Documents/fa feces/fa tabellen/FA.alltimes.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Boxplot der FA je Zeitpunkt
Melt Daten
FA_stool.melt <- melt(FA_stool_pairs, id.vars = 'Time', measure.vars = c('sat', 'mono.unsat', 'di.unsat', 'more.2.unsat', 'less.14', 'c14.17', 'c18', 'c20.24', 'total'))
FA_stool.melt <- dplyr::rename(FA_stool.melt, FA=variable)
FA_stool.melt <- dplyr::rename(FA_stool.melt, Concentration=value)
ggplot(FA_stool.melt,aes(x=Time, y=Concentration, fill= FA)) +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("saturated", "monounsaturated", "diunsaturated", "> 2 unsaturated", "< c14", "c 14-17", "c 18-19", "c 20-21", "c 22-24", "total", "iso", "anteiso"),
values = c("tomato", "yellowgreen", "steelblue2", "orchid2", "deeppink", "brown4", "darkorange1", "blueviolet", "aquamarine3", "darksalmon", "cyan3", "darkgreen")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))
Plots, die in Arbeit vorkommen
nach Saettigung
FA_stool.melt.sat <- melt(FA_stool_pairs, id.vars = 'Time', measure.vars = c('sat', 'mono.unsat', 'di.unsat', 'more.2.unsat'))
FA_stool.melt.sat <- dplyr::rename(FA_stool.melt.sat, FA=variable)
FA_stool.melt.sat <- dplyr::rename(FA_stool.melt.sat, Concentration=value)
FA_stool.melt.sat$Time <- factor(FA_stool.melt.sat$Time, levels = c("PRE", "POST"))
pdf("/Users/student05/Documents/fertige Plots/FA.DB.KD.pdf",width=8, height=10)
ggplot(FA_stool.melt.sat,aes(x=Time, y=Concentration, fill= FA)) +
xlab ('Zeitpunkt') + ylab ('Konzentration [nmol/g]') +
geom_boxplot(width = .7, lwd=0.7) + theme_classic()+
scale_fill_manual(labels = c("0", "1", "2", "3-6"),
values = c("#f0f9e8", "#bae4bc", "#7bccc4", "#2b8cbe")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),axis.text=element_text(size=16))+
theme(legend.position="top")
dev.off()
MCTs
FA_stool.melt.mct <- melt(FA_stool_pairs, id.vars = 'Time', measure.vars = c('less.14'))
FA_stool.melt.mct <- dplyr::rename(FA_stool.melt.mct, FA=variable)
FA_stool.melt.mct <- dplyr::rename(FA_stool.melt.mct, Concentration=value)
pdf("/Users/student05/Documents/fertige Plots/FA.MCT.KD.pdf",width=8, height=10)
ggplot(FA_stool.melt.mct,aes(x=Time, y=Concentration, fill= FA)) +
xlab ('Zeitpunkt') + ylab ('Konzentrationen [nmol/g]') +
geom_boxplot(width = .7, lwd=0.7) +
scale_fill_manual(labels = c("MCT"),
values = c("navy")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE")))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),axis.text=element_text(size=16))+
theme(legend.position="top")
dev.off()
Kettenlaenge
FA_stool.melt.kl <- melt(FA_stool_pairs, id.vars = 'Time', measure.vars = c('less.14','c14.17', 'c18', 'c20.24'))
FA_stool.melt.kl$Time <- factor(FA_stool.melt.kl$Time, levels = c("PRE", "POST"))
FA_stool.melt.kl <- dplyr::rename(FA_stool.melt.kl, FA=variable)
FA_stool.melt.kl <- dplyr::rename(FA_stool.melt.kl, Concentration=value)
pdf("/Users/student05/Documents/fertige Plots/FA.KL.KD.pdf",width=8, height=10)
ggplot(FA_stool.melt.kl,aes(x=Time, y=Concentration, fill= FA)) +
xlab ('Zeitpunkt') + ylab ('Konzentration [nmol/g]') +
geom_boxplot(width = .7, lwd=0.7) + theme_classic()+
scale_fill_manual(labels = c("> 14 c (MCT)","c 14-17", "c 18", "c 20-24"),
values = c("#f1eef6", "#bdc9e1", "#74a9cf", "#0570b0")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),axis.text=element_text(size=16))+
theme(legend.position="top")
dev.off()
Total FA
FA_stool.melt.t <- melt(FA_stool_pairs, id.vars = 'Time', measure.vars = c('total'))
FA_stool.melt.t <- dplyr::rename(FA_stool.melt.t, FA=variable)
FA_stool.melt.t <- dplyr::rename(FA_stool.melt.t, Concentration=value)
pdf("/Users/student05/Documents/fertige Plots/FA.total.KD.pdf",width=6, height=10)
ggplot(FA_stool.melt.t,aes(x=Time, y=Concentration, fill= FA)) +
xlab ('Zeitpunkt') + ylab ('Konzentration [nmol/g]') +
geom_boxplot(width = .2, lwd=1) + theme_classic()+
scale_fill_manual(labels = c("Gesamtfettsäuren"),
values = c("cornflowerblue")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),axis.text=element_text(size=16))+
theme(legend.position="top")+
expand_limits(y=c(0, 3000))
dev.off()
Omega-FA
FA_stool.melt.o <- melt(FA_stool_pairs, id.vars = 'Time', measure.vars = c('Omega3', 'Omega6','ratio'))
FA_stool.melt.o <- dplyr::rename(FA_stool.melt.o, FA=variable)
FA_stool.melt.o <- dplyr::rename(FA_stool.melt.o, Concentration=value)
FA_stool.melt.o$Time <- factor(FA_stool.melt.o$Time, levels = c("PRE", "POST"))
pdf("/Users/student05/Documents/fertige Plots/FA.omega.KD.pdf",width=8, height=10)
ggplot(FA_stool.melt.o,aes(x=Time, y=Concentration, fill= FA)) +
xlab ('Zeitpunkt') + ylab ('Konzentration [nmol/g]') +
geom_boxplot(width = .6, lwd=0.7) + theme_classic()+
scale_fill_manual(labels = c("alpha-Linolensäure", "Linolsäure", "Omega 6/Omega 3 Verhältnis"),
values = c("#2c7fb8", "#7fcdbb", "#edf8b1")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),axis.text=element_text(size=16))+
theme(legend.position="top")+
expand_limits(y=c(0, 3000))
dev.off()
In Arbeit Korrelation zwischen Saettigung der Fettsaeuren und Konzentration
FA_stool.melt.kl$chain.length <- as.integer(FA_stool.melt.kl$chain.length)
FA_stool.melt.kl <- melt(FA_stool_pairs_PP, id.vars = 'Time', measure.vars = c( 'less.14', 'c14.17', 'c18'))
FA_stool.melt.kl.pre <- subset(filter(FA_stool.melt.kl, !Time =='POST'))
FA_stool.melt.kl <- dplyr::rename(FA_stool.melt.kl, chain.length=variable)
FA_stool.melt.kl <- dplyr::rename(FA_stool.melt.kl, Concentration=value)
pdf("/Users/student05/Documents/fertige Plots/KL.Konzentration.pdf",width=8, height=10)
ggscatter(FA_stool.melt.kl, x='chain.length', y='Concentration',color = 'Time', palette = c('skyblue', 'orchid'), add = 'reg.line', conf.int = T,
cor.coef = T, cor.method = 'spearman',cor.coef.coord = c(1, 2500), cor.coef.size = 5, xlab= '..', ylab = 'Konzentration [nmol/g]')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
dev.off()
pdf("/Users/student05/Documents/fertige Plots/KL.Konzentration2.pdf",width=8, height=10)
ggscatter(FA_stool.melt.kl, x='chain.length', y='Concentration', add = 'reg.line', color = "grey59",fill = "lightgray",conf.int = T,
cor.coef = T, cor.method = 'spearman',cor.coef.coord = c(1, 2500), cor.coef.size = 8, xlab= '..', ylab = 'Konzentration [nmol/g]')+
theme(strip.text.x = element_text(size = 20, colour = "black"))+
theme(text = element_text(size=20),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")+
geom_point(color='black', size=2.5)
dev.off()
cor.test(subset(filter(FA_stool.melt.kl))$chain.length, subset(filter(FA_stool.melt.kl))$Concentration, method = "spearman", exact = F)
p.adjust(c(2.2e-16), method = 'BH', n=1)
(S = 87355, p-value < 2.2e-16 alternative hypothesis: true rho is not equal to 0 sample estimates: rho 0.8619349 q-value =2.2e-16)
Boxplots einzelner FAs zu den Zeitpunkten PRE und POST
von gesaettigten FA bis Total FA
FA_stool.melt.sat <- melt(FA_stool_pairs_PP, id.vars = 'Time', measure.vars = c('sat'))
FA_stool.melt.sat <- rename(FA_stool.melt.sat, FA=variable)
FA_stool.melt.sat <- rename(FA_stool.melt.sat, Concentration=value)
ggplot(FA_stool.melt.sat,aes(x=Time, y=Concentration, fill= FA)) +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("saturated"),
values = c("tomato")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons = comparison_time)
FA_stool.melt.ms <- melt(FA_stool_pairs_PP, id.vars = 'Time', measure.vars = c('mono.unsat'))
FA_stool.melt.ms <- rename(FA_stool.melt.ms, FA=variable)
FA_stool.melt.ms <- rename(FA_stool.melt.ms, Concentration=value)
comparison_time <- list(c("PRE", "POST"))
ggplot(FA_stool.melt.ms,aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ FA) +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("monounsaturated"),
values = c("yellowgreen")) +
theme(legend.position="top")+
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons = comparison_time)
FA_stool.melt.ds <- melt(FA_stool_pairs_PP, id.vars = 'Time', measure.vars = c('di.unsat'))
FA_stool.melt.ds <- rename(FA_stool.melt.ds, FA=variable)
FA_stool.melt.ds <- rename(FA_stool.melt.ds, Concentration=value)
comparison_time <- list(c("PRE", "POST"))
ggplot(FA_stool.melt.ds,aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ FA) +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("diunsaturated"),
values = c("steelblue2")) +
theme(legend.position="top")+
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons = comparison_time)
FA_stool.melt.m2u <- melt(FA_stool_pairs_PP, id.vars = 'Time', measure.vars = c('more.2.unsat'))
FA_stool.melt.m2u <- rename(FA_stool.melt.m2u, FA=variable)
FA_stool.melt.m2u <- rename(FA_stool.melt.m2u, Concentration=value)
comparison_time <- list(c("PRE", "POST"))
ggplot(FA_stool.melt.m2u,aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ FA) +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("> 2 unsaturated"),
values = c("orchid2")) +
theme(legend.position="top")+
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons = comparison_time)
FA_stool.melt.14 <- melt(FA_stool_pairs_PP, id.vars = 'Time', measure.vars = c('less.14'))
FA_stool.melt.14 <- rename(FA_stool.melt.14, FA=variable)
FA_stool.melt.14 <- rename(FA_stool.melt.14, Concentration=value)
comparison_time <- list(c("PRE", "POST"))
ggplot(FA_stool.melt.14,aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ FA) +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("< c14"),
values = c("deeppink")) +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons = comparison_time)+ theme(legend.position="top")
FA_stool.melt.1417 <- melt(FA_stool_pairs_PP, id.vars = 'Time', measure.vars = c('c14.17'))
FA_stool.melt.1417 <- rename(FA_stool.melt.1417, FA=variable)
FA_stool.melt.1417 <- rename(FA_stool.melt.1417, Concentration=value)
comparison_time <- list(c("PRE", "POST"))
ggplot(FA_stool.melt.1417,aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ FA) +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("c 14-17"),
values = c("brown4")) +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons = comparison_time)
FA_stool.melt.1417 <- melt(FA_stool_pairs, id.vars = 'Time', measure.vars = c('c14.17'))
FA_stool.melt.1417 <- rename(FA_stool.melt.1417, FA=variable)
FA_stool.melt.1417 <- rename(FA_stool.melt.1417, Concentration=value)
comparison_time <- list(c("PRE", "POST"))
ggplot(FA_stool.melt.1417,aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ FA) +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("c 14-17"),
values = c("brown4")) +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons = comparison_time)+ theme(legend.position="top")
FA_stool.melt.18 <- melt(FA_stool_pairs_PP, id.vars = 'Time', measure.vars = c('c18.19'))
FA_stool.melt.18 <- rename(FA_stool.melt.18, FA=variable)
FA_stool.melt.18 <- rename(FA_stool.melt.18, Concentration=value)
comparison_time <- list(c("PRE", "POST"))
ggplot(FA_stool.melt.18,aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ FA) +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("c 18-19"),
values = c("darkorange1")) +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons = comparison_time)+ theme(legend.position="top")
FA_stool.melt.20 <- melt(FA_stool_pairs_PP, id.vars = 'Time', measure.vars = c('c20.21'))
FA_stool.melt.20 <- rename(FA_stool.melt.20, FA=variable)
FA_stool.melt.20 <- rename(FA_stool.melt.20, Concentration=value)
comparison_time <- list(c("PRE", "POST"))
ggplot(FA_stool.melt.20,aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ FA) +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("c 20-21"),
values = c("blueviolet")) +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons = comparison_time)+ theme(legend.position="top")
FA_stool.melt.22 <- melt(FA_stool_pairs_PP, id.vars = 'Time', measure.vars = c('c22.24'))
FA_stool.melt.22 <- rename(FA_stool.melt.22, FA=variable)
FA_stool.melt.22 <- rename(FA_stool.melt.22, Concentration=value)
comparison_time <- list(c("PRE", "POST"))
ggplot(FA_stool.melt.22,aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ FA) +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("c 22-24"),
values = c("aquamarine3")) +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons = comparison_time)+ theme(legend.position="top")
FA_stool.melt.t <- melt(FA_stool_pairs_PP, id.vars = 'Time', measure.vars = c('total'))
FA_stool.melt.t <- rename(FA_stool.melt.t, FA=variable)
FA_stool.melt.t <- rename(FA_stool.melt.t, Concentration=value)
comparison_time <- list(c("PRE", "POST"))
ggplot(FA_stool.melt.t,aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ FA) +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("total"),
values = c("darksalmon")) +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons = comparison_time)+ theme(legend.position="top")
Korrelation zwischen Anzahl an Doppelbindungen und Konzentration der FA
Laden der Metadaten
FA_stool.db <- read.table("/Users/student05/Documents/DB sättigung .txt", sep = '\t', comment='',
head=T)
FA_stool.db$Time <- factor(FA_stool.db$Time, levels = c("PRE", "POST"))
Plotten der Korrelation In Arbeit
pdf("/Users/student05/Documents/fertige Plots/DB.2Konzentration.pdf",width=8, height=10)
ggscatter(FA_stool.db, x='DB', y='Concentration',color = "grey59",fill = "lightgray",shape = 19, add = 'reg.line', conf.int = T,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0, 3000), cor.coef.size = 5, xlab= 'Anzahl an Doppelbindungen', ylab = 'Konzentration [nmol/g]')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")+
geom_point(color='black', size=2.5)
dev.off()
cor.test(subset(filter(FA_stool.db))$DB, subset(filter(FA_stool.db))$Concentration, method = "spearman", exact = F)
p.adjust(c(2.2e-16), method = 'BH', n=1)
(S = 3684500, p-value < 2.2e-16 alternative hypothesis: true rho is not equal to 0 sample estimates: rho -0.7034807)
2.2 Korrelationsanalysen zwischen den FAs mit Hilfe einer Korrelationsmatrix
Laden der Metadaten
FA_stool <- read.table("/Users/student05/Documents/fa feces/Fa.feces.2.txt", sep = '\t', comment='',
head=T)
FA_stool$Time <-factor(FA_stool$Time, levels = c("PRE", "POST"))
FA_stool <- FA_stool[-c(58:64),]
FA_stool <- FA_
FA_stool<- add_rownames(FA_stool, "SampleID1")
FA_stool.r<- add_rownames(FA_stool, "SampleID1")
row.names(FA_stool) <- FA_stool$SampleID
Filtern nach PRE und POST Hinzufügen von Spearman
FA_stool_matrix_PRE <- subset(filter(FA_stool, Time == "PRE"))[ ,8:19]
FA_stool_matrix_POST <- subset(filter(FA_stool, Time == "POST"))[ ,8:19]
res.PRE <- cor(FA_stool_matrix_PRE)
res.POST <- cor(FA_stool_matrix_POST)
res2.PRE <- rcorr(as.matrix(FA_stool_matrix_PRE), type = "spearman")
res2.POST <- rcorr(as.matrix(FA_stool_matrix_POST), type = "spearman")
Bestimmung des Korrelationskoeffizienten
res2.PRE$r
res2.POST$r
FA_stool_PRE_CC <- as.matrix((res2.PRE$r))
FA_stool_POST_CC <- as.matrix(res2.POST$r)
Bestimmung p-values
res2$P
FA_stool_PRE_PV <- as.matrix(res2.PRE$P)
FA_stool_POST_PV <- as.matrix(res2.POST$P)
Erstellen einer flattenCorrMatrix für PRE und POST
flattenCorrMatrix.PRE <- function(FA_stool_PRE_CC, FA_stool_PRE_PV) {
ut <- upper.tri(FA_stool_PRE_CC)
data.frame(
row = rownames(FA_stool_PRE_CC)[row(FA_stool_PRE_CC)[ut]],
column = rownames(FA_stool_PRE_CC)[col(FA_stool_PRE_CC)[ut]],
cor =(FA_stool_PRE_CC)[ut],
p = FA_stool_PRE_PV[ut]
)
}
flattenCorrMatrix.PRE(res2.PRE$r, res2.PRE$P)
flattenCorrMatrix.POST <- function(FA_stool_POST_CC, FA_stool_POST_PV) {
ut <- upper.tri(FA_stool_POST_CC)
data.frame(
row = rownames(FA_stool_POST_CC)[row(FA_stool_POST_CC)[ut]],
column = rownames(FA_stool_POST_CC)[col(FA_stool_POST_CC)[ut]],
cor =(FA_stool_POST_CC)[ut],
p = FA_stool_POST_PV[ut]
)
}
flattenCorrMatrix.POST(res2.POST$r, res2.POST$P)
Dataframe erstellen und Spalten umbenennen
FA_PRE_cor.p <- as.data.frame(flattenCorrMatrix.PRE(res2.PRE$r, res2.PRE$P))
FA_POST_cor.p <- as.data.frame(flattenCorrMatrix.POST(res2.POST$r, res2.POST$P))
colnames(FA_PRE_cor.p) <- c("FA", "FA", "correlation coefficient", "p-value")
colnames(FA_POST_cor.p) <- c("FA", "FA", "correlation coefficient", "p-value")
Correlogram erstellen
corrplot(res.PRE, type = "upper", order = "hclust",
tl.col = "black", tl.srt = 45)
corrplot(res.POST, type = "upper", order = "hclust",
tl.col = "black", tl.srt = 45)
corrplot(res2.PRE$r, type="upper", order="hclust",
p.mat = res2.PRE$P, sig.level = 0.05, insig = "blank")
corrplot(res2.PRE$r, type="upper", order="hclust",
p.mat = res2.PRE$P, sig.level = 0.05, insig = "blank")
corrplot(res2.POST$r, type="upper", order="hclust",
p.mat = res2.POST$P, sig.level = 0.05, insig = "blank")
corrplot(res2.POST$r, type="upper", order="hclust", p.mat = res2.PRE$P, sig.level = 0.05, insig = "blank")
Scatter Plot erstellen und Daten sichern
chart.Correlation(FA_stool_matrix_PRE, histogram=TRUE, pch=19)
chart.Correlation(FA_stool_matrix_POST, histogram = T, pch = 19)
write.table(FA_POST_cor.p, file ='/Users/student05/Documents/fa feces/FA fecal/correlations/FA post correlations cor p',sep ="\t", col.names = TRUE, row.names = FALSE)
write.table(FA_PRE_cor.p, file ='/Users/student05/Documents/fa feces/FA fecal/correlations/FA pre correlations cor p',sep ="\t", col.names = TRUE, row.names = FALSE)
2.3 Sterolkonvertierungstypen-Analyse der FA
Laden und filtern der Metadaten
FA_stool <- read.table("/Users/student05/Documents/fa feces/Fa.feces.2.txt", sep = '\t', comment='',
head=T)
FA_stool$Time <-factor(FA_stool$Time, levels = c("PRE", "POST", "FOLLOW-UP"))
FA_stool <- FA_stool[-c(65, 66), ]
row.names(FA_stool) <- FA_stool$SampleID
FA_stool$Time <-factor(FA_stool$Time, levels = c("PRE", "POST", "FOLLOW-UP"))
FA_stool[1,4]<- "PRE"
FA_stool_pairs <- filter(FA_stool, Proband == "05AP" | Proband == "06WT"
| Proband == "07RW" | Proband == "13BS" | Proband == "17SK"
| Proband == "22WS" | Proband == "25FE" | Proband == "26FB"
| Proband == "28HM" | Proband == "29MK" | Proband == "30HB"
| Proband == "31KE" | Proband == "32FG" | Proband == "36ER"
| Proband == "37SD" | Proband == "38AR" | Proband == "40WA"
| Proband == "41ML" | Proband == "45GL" | Proband == "47OT"
| Proband == "50DM" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
FA_stool_pairs_PP <- filter(FA_stool_pairs, Time=="PRE" | Time=="POST")
FA_stool_pairs_PPFU <- filter(FA_stool, Proband == "05AP" | Proband == "13
BS" | Proband == "17SK" | Proband == "22WS" | Proband ==
"40WA" | Proband == "41ML" | Proband == "54SL")
In high und low Converter unterteilen
lowconv <- filter(FA_stool, Proband == "05AP" | Proband == "33MP"
| Proband == "38AR" | Proband == "40WA" | Proband == "41ML"
| Proband == "47OT" | Proband == "49RJ" | Proband == "50DM")
lowconv['Phenotype'] = 'low converter'
highconv <- filter(FA_stool, Proband == "06WT" | Proband == "07RW"
| Proband == "13BS" | Proband == "17SK" | Proband == "22WS"
| Proband == "25FE" | Proband == "26FB" | Proband == "29MK"
| Proband == "30HB" | Proband == "31KE" | Proband == "36ER"
| Proband == "45GL" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
highconv['Phenotype'] = 'high converter'
highconv$Converter.Type <- NULL
lowconv$Converter.Type <- NULL
noconv <- filter(FA_stool, Proband == "28HM" | Proband == "32FG"
| Proband == "34WF" | Proband == "35AD" | Proband == "37SD"
| Proband == "39DA" | Proband == "66DG" | Proband == "70PL")
noconv['Phenotype'] = 'not classified'
noconv$Converter.Type <- NULL
convT <- data.frame()
convT <- bind_rows(lowconv, highconv, noconv)
convT_paired <- filter(convT, Proband == "05AP" | Proband == "06WT"
| Proband == "07RW" | Proband == "13BS" | Proband == "17SK"
| Proband == "22WS" | Proband == "25FE" | Proband == "26FB"
| Proband == "28HM" | Proband == "29MK" | Proband == "30HB"
| Proband == "31KE" | Proband == "32FG" | Proband == "36ER"
| Proband == "37SD" | Proband == "38AR" | Proband == "40WA"
| Proband == "41ML" | Proband == "45GL" | Proband == "47OT"
| Proband == "50DM" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
convT_paired_PP <- filter(convT_paired, Time=="PRE" | Time=="POST")
convT_paired_PPnc <- filter(subset(convT_paired_PP, !Phenotype == "not classified" ))
convT_paired_PPnc.PRE <- filter(subset(convT_paired_PPnc, Time =="PRE"))
convT_paired_PPnc.POST <- filter(subset(convT_paired_PPnc, Time =="POST"))
write.table(convT, file = '/Users/student05/Documents/fa feces/FA sterol converter types ', sep = "\t", col.names = TRUE,row.names = FALSE)
In high und low Converter unterteilen
lowconv <- filter(FA_stool, Proband == "05AP" | Proband == "33MP"
| Proband == "38AR" | Proband == "40WA" | Proband == "41ML"
| Proband == "47OT" | Proband == "49RJ" | Proband == "50DM")
lowconv['Phenotype'] = 'low converter'
highconv <- filter(FA_stool, Proband == "06WT" | Proband == "07RW"
| Proband == "13BS" | Proband == "17SK" | Proband == "22WS"
| Proband == "25FE" | Proband == "26FB" | Proband == "29MK"
| Proband == "30HB" | Proband == "31KE" | Proband == "36ER"
| Proband == "45GL" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
highconv['Phenotype'] = 'high converter'
highconv$Converter.Type <- NULL
lowconv$Converter.Type <- NULL
noconv <- filter(FA_stool, Proband == "28HM" | Proband == "32FG"
| Proband == "34WF" | Proband == "35AD" | Proband == "37SD"
| Proband == "39DA" | Proband == "66DG" | Proband == "70PL")
noconv['Phenotype'] = 'not classified'
noconv$Converter.Type <- NULL
convT <- data.frame()
convT <- bind_rows(lowconv, highconv, noconv)
convT_paired <- filter(convT, Proband == "05AP" | Proband == "06WT"
| Proband == "07RW" | Proband == "13BS" | Proband == "17SK"
| Proband == "22WS" | Proband == "25FE" | Proband == "26FB"
| Proband == "28HM" | Proband == "29MK" | Proband == "30HB"
| Proband == "31KE" | Proband == "32FG" | Proband == "36ER"
| Proband == "37SD" | Proband == "38AR" | Proband == "40WA"
| Proband == "41ML" | Proband == "45GL" | Proband == "47OT"
| Proband == "50DM" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
convT_paired_PP <- filter(convT_paired, Time=="PRE" | Time=="POST")
convT_paired_PPnc <- filter(subset(convT_paired_PP, !Phenotype == "not classified" ))
convT_paired_PPnc.PRE <- filter(subset(convT_paired_PPnc, Time =="PRE"))
convT_paired_PPnc.POST <- filter(subset(convT_paired_PPnc, Time =="POST"))
write.table(convT, file = '/Users/student05/Documents/fa feces/FA sterol converter types ', sep = "\t", col.names = TRUE,row.names = FALSE)
Boxplot aller FA je nach Sterolkonvertierungstyp und Zeitpunkt Melt Datenset Alle FA
FA_stool.melt <- melt(convT_paired_PP, id.vars = c('Phenotype', 'Time'), measure.vars = c('sat', 'mono.unsat', 'di.unsat', 'more.2.unsat', 'less.14', 'c14.17', 'c18.19', 'c20.21', 'c22.24', 'total'))
FA_stool.melt <- subset(filter(FA_stool.melt, !Phenotype == "not classified"))
FA_stool.melt <- rename(FA_stool.melt, FA=variable)
FA_stool.melt <- rename(FA_stool.melt, Concentration=value)
ggplot(FA_stool.melt,aes(x=Phenotype, y=Concentration, fill= FA)) +
xlab ('Converter type') + ylab ('Concentration [nmol/g DW]') +
geom_boxplot()+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
facet_grid(.~Time)+
scale_fill_manual(labels = c("saturated", "monounsaturated", "diunsaturated", "> 2 unsaturated", "< c14", "c 14-17", "c 18-19", "c 20-21", "c 22-24", "total"),
values = c("tomato", "yellowgreen", "steelblue2", "orchid2", "deeppink", "brown4", "darkorange1", "blueviolet", "aquamarine3", "darksalmon"))
+theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Gesaettigte FA + wilcoxon test in Arbeit
sat_stool.melt <- melt(convT_paired_PP, id.vars = c('Phenotype','Time'), measure.vars = c('sat'))
sat_stool.melt <- rename(sat_stool.melt, FA=variable)
sat_stool.melt <- rename(sat_stool.melt, Concentration=value)
ggplot(filter(sat_stool.melt, !Time=="FOLLOW-UP" & !Phenotype=="not classified"),aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/g]') +
scale_fill_manual(labels=c("Saturated fatty acids"), values = c("yellowgreen"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(filter(sat_stool.melt, !Phenotype=="not classified"),aes(x=Phenotype, y=Concentration, fill= FA)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/g] ') +
scale_fill_manual(labels=c("saturated fatty acid"), values = c("yellowgreen"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
mean(subset(filter(convT_paired_PP, Time == "PRE" & Phenotype == "high converter"))$sat)
sd(subset(filter(convT_paired_PP, Time == "PRE" & Phenotype == "high converter"))$sat)
mean(subset(filter(convT_paired_PP, Time == "POST" & Phenotype == "high converter"))$sat)
sd(subset(filter(convT_paired_PP, Time == "POST" & Phenotype == "high converter"))$sat)
mean(subset(filter(convT_paired_PP, Time == "PRE" & Phenotype == "low converter"))$sat)
sd(subset(filter(convT_paired_PP, Time == "PRE" & Phenotype == "low converter"))$sat)
mean(subset(filter(convT_paired_PP, Time == "POST" & Phenotype == "low converter"))$sat)
sd(subset(filter(convT_paired_PP, Time == "POST" & Phenotype == "low converter"))$sat)
pairwise.wilcox.test(subset(filter(convT_paired_PP, Time == "PRE"))$sat, subset(filter(convT_paired_PP, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(convT_paired_PP, Time == "POST"))$sat, subset(filter(convT_paired_PP, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(convT_paired_PP, Phenotype == "low converter"))$sat, subset(filter(convT_paired_PP, Phenotype == "low converter"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(convT_paired_PP, Phenotype == "high converter"))$sat, subset(filter(convT_paired_PP, Phenotype == "high converter"))$Time, p.adjust.method = 'BH', paired = F)
sat_stool.melt <- melt(convT_paired_PP, id.vars = c('Phenotype','Time'), measure.vars = c('sat'))
sat_stool.melt$Time <-factor(sat_stool.melt$Time, levels = c("PRE", "POST"))
sat_stool.melt <- dplyr::rename(sat_stool.melt, FA=variable)
sat_stool.melt <- dplyr::rename(sat_stool.melt, Concentration=value)
pdf("/Users/student05/Documents/fertige Plots/converter.sat.pdf",width=8, height=10)
ggplot(filter(sat_stool.melt, !Phenotype=="not classified"),aes(x=Phenotype, y=Concentration, fill= Phenotype)) +facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Gesättigte Fettsäurenkonzentration [nmol/g] ') +
scale_fill_manual(labels=c("high converter", "low converter"), values = c("seashell4", "seashell2"))+
geom_boxplot(width = .7, lwd=0.6) + theme_classic() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("low converter")))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
dev.off()
Total FA
total_stool.melt <- melt(convT_paired_PP, id.vars = c('Phenotype','Time'), measure.vars = c('total'))
total_stool.melt <- rename(total_stool.melt, FA=variable)
total_stool.melt <- rename(total_stool.melt, Concentration=value)
ggplot(filter(total_stool.melt, !Time=="FOLLOW-UP" & !Phenotype=="not classified"),aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/g]') +
scale_fill_manual(labels=c("total fatty acids"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))
ggplot(filter(total_stool.melt, !Phenotype=="not classified"),aes(x=Phenotype, y=Concentration, fill= FA)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/g] ') +
scale_fill_manual(labels=c("total fatty acid"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
einfach ungesaettigt
mono.unsat_stool.melt <- melt(convT_paired_PP, id.vars = c('Phenotype','Time'), measure.vars = c('mono.unsat'))
mono.unsat_stool.melt <- rename(mono.unsat_stool.melt, FA=variable)
mono.unsat_stool.melt <- rename(mono.unsat_stool.melt, Concentration=value)
ggplot(filter(mono.unsat_stool.melt, !Time=="FOLLOW-UP" & !Phenotype=="not classified"),aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/g]') +
scale_fill_manual(labels=c("mono unsaturated fatt acids"), values = c("coral2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))
ggplot(filter(mono.unsat_stool.melt, !Phenotype=="not classified"),aes(x=Phenotype, y=Concentration, fill= FA)) +facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/g] ') +
scale_fill_manual(labels=c("mono unsaturated fatty acid"), values = c("coral2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))
zweifach ungesaettigt + wilcoxon test in Arbeit
di.unsat_stool.melt <- melt(convT_paired_PP, id.vars = c('Phenotype','Time'), measure.vars = c('di.unsat'))
di.unsat_stool.melt <- rename(di.unsat_stool.melt, FA=variable)
di.unsat_stool.melt <- rename(di.unsat_stool.melt, Concentration=value)
ggplot(filter(di.unsat_stool.melt, !Time=="FOLLOW-UP" & !Phenotype=="not classified"),aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/g]') +
scale_fill_manual(labels=c("diunsaturated fatty acid"), values = c("seashell4"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))
mean(subset(filter(convT_paired_PP, Time == "PRE" & Phenotype == "high converter"))$di.unsat)
sd(subset(filter(convT_paired_PP, Time == "PRE" & Phenotype == "high converter"))$di.unsat)
mean(subset(filter(convT_paired_PP, Time == "POST" & Phenotype == "high converter"))$di.unsat)
sd(subset(filter(convT_paired_PP, Time == "POST" & Phenotype == "high converter"))$di.unsat)
mean(subset(filter(convT_paired_PP, Time == "PRE" & Phenotype == "low converter"))$di.unsat)
sd(subset(filter(convT_paired_PP, Time == "PRE" & Phenotype == "low converter"))$di.unsat)
mean(subset(filter(convT_paired_PP, Time == "POST" & Phenotype == "low converter"))$di.unsat)
sd(subset(filter(convT_paired_PP, Time == "POST" & Phenotype == "low converter"))$di.unsat)
pairwise.wilcox.test(subset(filter(convT_paired_PP, Time == "PRE"))$di.unsat, subset(filter(convT_paired_PP, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(convT_paired_PP, Time == "POST"))$di.unsat, subset(filter(convT_paired_PP, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(convT_paired_PP, Phenotype == "low converter"))$di.unsat, subset(filter(convT_paired_PP, Phenotype == "low converter"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(convT_paired_PP, Phenotype == "high converter"))$di.unsat, subset(filter(convT_paired_PP, Phenotype == "high converter"))$Time, p.adjust.method = 'BH', paired = F)
pdf("/Users/student05/Documents/fertige Plots/converter.unsat.pdf",width=8, height=10)
ggplot(filter(di.unsat_stool.melt, !Phenotype=="not classified"),aes(x=Phenotype, y=Concentration, fill= Phenotype)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Zweifach ungesättigte Fettsäurenkonzentration [nmol/g] ') +
scale_fill_manual(labels=c("high converter", "low converter"), values = c("seashell4", "seashell2"))+
geom_boxplot(width = .7, lwd=0.6) + theme_classic() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
dev.off()
Omega6/Omega3-ratio
sat_stool.omega <- melt(convT_paired_PP, id.vars = c('Phenotype','Time'), measure.vars = c('ratio'))
sat_stool.omega$Time <-factor(sat_stool.omega$Time, levels = c("PRE", "POST"))
sat_stool.omega <- dplyr::rename(sat_stool.omega, FA=variable)
sat_stool.omega <- dplyr::rename(sat_stool.omega, Concentration=value)
ggplot(filter(sat_stool.omega, !Phenotype=="not classified"),aes(x=Phenotype, y=Concentration, fill= Phenotype)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Gesättigte Fettsäurenkonzentration [nmol/g] ') +
scale_fill_manual(labels=c("high converter", "low converter"), values = c("seashell4", "seashell2"))+
geom_boxplot(width = .7, lwd=0.6) + theme_classic() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("low converter", "high converter")))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
mehr als zweifach ungesaettigt
more.2.unsat_stool.melt <- melt(convT_paired_PP, id.vars = c('Phenotype','Time'), measure.vars = c('more.2.unsat'))
more.2.unsat_stool.melt <- rename(more.2.unsat_stool.melt, FA=variable)
more.2.unsat_stool.melt <- rename(more.2.unsat_stool.melt, Concentration=value)
ggplot(filter(more.2.unsat_stool.melt, !Time=="FOLLOW-UP" & !Phenotype=="not classified"),aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/g]') +
scale_fill_manual(labels=c("> 2 unsaturated"), values = c("brown4"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))
ggplot(filter(more.2.unsat_stool.melt, !Phenotype=="not classified"),aes(x=Phenotype, y=Concentration, fill= FA)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/g] ') +
scale_fill_manual(labels=c("> 2 unsaturated"), values = c("brown4"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))
C18
c18.19_stool.melt <- melt(convT_paired_PP, id.vars = c('Phenotype','Time'), measure.vars = c('c18.19'))
c18.19_stool.melt <- rename(c18.19_stool.melt, FA=variable)
c18.19_stool.melt <- rename(c18.19_stool.melt, Concentration=value)
ggplot(filter(c18.19_stool.melt, !Time=="FOLLOW-UP" & !Phenotype=="not classified"),aes(x=Time, y=Concentration, fill= FA)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/g]') +
scale_fill_manual(labels=c("18-19 c-atomes"), values = c("yellow2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))
ggplot(filter(c18.19_stool.melt, !Phenotype=="not classified"),aes(x=Phenotype, y=Concentration, fill= FA)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/g] ') +
scale_fill_manual(labels=c("18-19 c-atomes"), values = c("yellow2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))
2.3 Alpha-Diversitaet und FAs Shannon und Simpson
Laden und filtern der Metadaten
map_alphadiv <- read.table("/Users/student05/Downloads/means_alpha_div.txt", sep = '\t', comment='',head = TRUE, row.names = 1)
FA_stool <- read.table("/Users/student05/Documents/fa feces/Fa.feces.2.txt", sep = '\t', comment='',
head=T)
View(FA_stool)
FA_stool$Time <-factor(FA_stool$Time, levels = c("PRE", "POST", "FOLLOW-UP"))
FA_stool <- FA_stool[-c(58:64), ]
row.names(FA_stool) <- FA_stool$SampleID
Synchonisieren der Datensets
common.ids.St <- intersect(rownames(FA_stool), rownames(map_alphadiv))
common.ids.St <- intersect(row.names(FA_stool), row.names(map_alphadiv))
FA_stool <- FA_stool[common.ids.St,]
map_alphadiv <- map_alphadiv[common.ids.St,]
FA_stool$Shannon <- map_alphadiv$Shannon
FA_stool$Simpson <- map_alphadiv$Simpson
Loop Korrelation Shannon und FAs
corr_colnames_FA <-colnames(FA_stool[,7:18])
corr_spearman_Shannon_FA <- data.frame()
for( i in unique(corr_colnames_FA)) {
tmp <- filter(FA_stool, !is.na(i))
x = as.matrix(as.data.frame(lapply(tmp[,i], as.numeric)))
y = t(as.matrix(tmp$Shannon) )
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "PRE"))[,i],as.numeric)))
w = t(as.matrix(subset(filter(tmp, Time == "PRE"))$Shannon))
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "POST"))[,i],as.numeric)))
s = t(as.matrix(subset(filter(tmp, Time == "POST"))$Shannon))
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Shannon_FA)+1
corr_spearman_Shannon_FA[nrow,"Div"] = "Shannon"
corr_spearman_Shannon_FA[nrow, "column"] = i
corr_spearman_Shannon_FA[nrow, "rho"] = rho
corr_spearman_Shannon_FA[nrow, "p.value"] = p
corr_spearman_Shannon_FA[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Shannon_FA[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Shannon_FA[nrow, "rho_POST"] = rho_POST
corr_spearman_Shannon_FA[nrow, "p.value_POST"] = p_POST
}
corr_spearman_Shannon_FA$p.adjusted <- p.adjust(corr_spearman_Shannon_FA$p.value,method = "BH", n = 12)
corr_spearman_Shannon_FA$p.adjusted_PRE <-p.adjust(corr_spearman_Shannon_FA$p.value_PRE, method = "BH", n = 12)
corr_spearman_Shannon_FA$p.adjusted_POST <- p.adjust(corr_spearman_Shannon_FA$p.value_POST, method = "BH", n = 12)
write.table(corr_spearman_Shannon_FA, file = '/Users/student05/Documents/fa feces/tabellen/Shannon.FA.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten Shannon und Fas die interessante Korrelation zeigen
ggplot(FA_stool, aes(x=total, y=Shannon)) + geom_point(aes(color=Time)) +
scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Total fatty acid Concentration [nmol/g]') +
ylab('Shannon-Index')
ggscatter(FA_stool, x='total', y='Shannon', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Total fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index') +
facet_wrap(~Time, scales = "free_x")+
theme(legend.position="none")
ggscatter(FA_stool, x='sat', y='Shannon', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index') +
facet_wrap(~Time)
ggscatter(FA_stool, x='anteiso', y='Shannon', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Anteiso fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index') +
facet_wrap(~Time)
ggscatter(FA_stool, x='c22.24', y='Shannon', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c 22-24 fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index') +
facet_wrap(~Time)
ggscatter(FA_stool, x='c20.21', y='Shannon', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c 20-21 fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index') +
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(FA_stool, x='c14.17', y='Shannon', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c 14-17 fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index') +
facet_wrap(~Time)
ggscatter(FA_stool, x='less.14', y='Shannon', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '< 14 c-atoms fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index') +
facet_wrap(~Time)
ggscatter(FA_stool, x='more.2.unsat', y='Shannon', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '> 2 unsaturated fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index') +
facet_wrap(~Time)
ggscatter(FA_stool, x='di.unsat', y='Shannon', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Diunsaturated fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index') +
facet_wrap(~Time)
ggscatter(FA_stool, x='sat', y='Shannon', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index')
ggscatter(FA_stool, x='di.unsat', y='Shannon', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Diunsaturated fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index')
ggscatter(FA_stool, x='more.2.unsat', y='Shannon', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '> 2 unsaturated fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index')
ggscatter(FA_stool, x='c20.21', y='Shannon', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c20-21 c atoms fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index')
ggscatter(FA_stool, x='c22.24', y='Shannon', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c22-24 c atoms fatty acid Concentration [nmol/g]', ylab = 'Shannon-Index')
in der Arbeit Total FA
pdf("/Users/student05/Documents/fertige Plots/Shannon.totalFA.pdf",width=8, height=10)
ggscatter(FA_stool, x='total', y='Shannon', add = 'reg.line',color = "grey59",fill = "lightgray", conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0,7), cor.coef.size = 8, xlab= 'Gesamte Fettsäurenkonzentrationen [nmol/g]', ylab = 'Shannon-Index')+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text( hjust=1))+
geom_point(color='black', size=2.5)
dev.off()
Korrelation zwischen Shannon und Kettenlaenge Laden der Metadaten
FA_stool.sh <- read.table("/Users/student05/Documents/DB shannon.txt", sep = '\t', comment='',
head=T)
FA_stool_sh_pr <- subset(filter(FA_stool.sh, !Time =="POST"))
FA_stool_sh_po <- subset(filter(FA_stool.sh, !Time =="PRE"))
Plotten der Daten
FA_stool_sh_pr$Shannon <- as.discrete(FA_stool_sh_pr$Shannon)
FA_stool_sh_pr$Concentration <- as.discrete(FA_stool_sh_pr$Concentration)
ggscatter(FA_stool_sh_pr, x='Concentration', y='Shannon',color = 'DB', palette = c('tomato', 'yellowgreen','steelblue'), add = 'reg.line', conf.int = T,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Concentration [nmol/g]', ylab = 'Shannon Index')+
facet_grid(.~ DB, scales="free")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(FA_stool_sh_po, x='Concentration', y='Shannon',color = 'DB', add = 'reg.line', conf.int = T,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(250, 7),xlab= 'Concentration [nmol/g]', ylab = 'Shannon Index')+
facet_grid(.~ DB, scales="free")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop Simpson und alle FAs
corr_spearman_Simpson_FA <- data.frame()
for( i in unique(corr_colnames_FA)) {
tmp <- filter(FA_stool, !is.na(i))
x = as.matrix(as.data.frame(lapply(tmp[,i], as.numeric)))
y = t(as.matrix(tmp$Simpson))
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "PRE"))[,i],as.numeric)))
w = t(as.matrix (subset(filter(tmp, Time == "PRE"))$Simpson))
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "POST"))[,i],as.numeric)))
s = t(as.matrix(subset(filter(tmp, Time == "POST"))$Simpson))
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Simpson_FA)+1
corr_spearman_Simpson_FA[nrow,"Div"] = "Simpson"
corr_spearman_Simpson_FA[nrow, "column"] = i
corr_spearman_Simpson_FA[nrow, "rho"] = rho
corr_spearman_Simpson_FA[nrow, "p.value"] = p
corr_spearman_Simpson_FA[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Simpson_FA[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Simpson_FA[nrow, "rho_POST"] = rho_POST
corr_spearman_Simpson_FA[nrow, "p.value_POST"] = p_POST
}
corr_spearman_Simpson_FA$p.adjusted <- p.adjust(corr_spearman_Simpson_FA$p.value,method = "BH", n = 12)
corr_spearman_Simpson_FA$p.adjusted_PRE <-p.adjust(corr_spearman_Simpson_FA$p.value_PRE, method = "BH", n = 12)
corr_spearman_Simpson_FA$p.adjusted_POST <- p.adjust(corr_spearman_Simpson_FA$p.value_POST, method = "BH", n = 12)
write.table(corr_spearman_Simpson_FA, file = '/Users/student05/Documents/fa feces/tabellen/Simpson.FA.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
corr_sig_Simpson_FA <- filter(corr_spearman_Simpson_FA, p.adjusted < 0.05 | p.adjusted_PRE < 0.5 | p.adjusted_POST < 0.5 | p.adjusted_FU < 0.5)
Plotten der Metadaten Simpson und interessante FAs
ggscatter(FA_stool, x='total', y='Shannon', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'),
add = 'reg.line', conf.int = TRUE, cor.coef= TRUE, cor.coef.coord = c(0,0.998),
cor.method = 'spearman', xlab= 'Saturated fatty acids Concentration [nmol/g]', ylab = 'Simpson-Index') +
facet_wrap(~Time, scales = "free_x")
ggscatter(FA_stool, x='total', y='Simpson', color = 'Time', palette = c('yellowgreen', 'coral2', 'steelblue2'),
add = 'reg.line', conf.int = TRUE, cor.coef= TRUE, cor.coef.coord = c(0,0.998),
cor.method = 'spearman', xlab= 'Total fatty acids Concentration [nmol/g]', ylab = 'Simpson-Index') +
facet_wrap(~Time)
ggscatter(FA_stool, x='sat', y='Simpson',
add = 'reg.line', conf.int = TRUE, cor.coef= TRUE, cor.coef.coord = c(0,0.998),
cor.method = 'spearman', xlab= 'Saturated fatty acids Concentration [nmol/g]', ylab = 'Simpson-Index')
ggscatter(FA_stool, x='total', y='Simpson',
add = 'reg.line', conf.int = TRUE, cor.coef= TRUE, cor.coef.coord = c(0,0.998),
cor.method = 'spearman', xlab= 'Total fatty acids Concentration [nmol/g]', ylab = 'Simpson-Index')
2.4 Korrelationsanalysen zwischen Taxa und den FAs
Laden und filtern der Metadaten, Pylum und Genus level setzen, Daten sichern
relab_means <- read.table('/Users/student05/Documents/relative abundance/relab_means_per_timepoint.txt', sep ='\t', comment='', head=T)
relab_means_melt <- melt(relab_means, id=c('Proband', 'Time'))
relab_means_melt <- dplyr::rename(relab_means_melt, Taxa=variable)
relab_means_melt <- dplyr::rename(relab_means_melt, Relative_Abundance=value)
relab_phylum <- subset(relab_means_melt, !grepl("g__|f__|o__|c__", relab_means_melt$Taxa))
relab_phylum <- subset(relab_phylum, !grepl("k__Archaea", relab_phylum$Taxa))
relab_phylum$Time <- factor(relab_phylum$Time, levels=c('PRE','POST','FOLLOW-UP'))
relab_phylum_spread <- spread(relab_phylum, Taxa, Relative_Abundance, sep = NULL)
relab_genus <- subset(relab_means_melt, grepl("g__", relab_means_melt$Taxa))
relab_genus <- subset(relab_genus, !grepl("k__Archaea", relab_genus$Taxa))
relab_genus$Time <- factor(relab_genus$Time, levels = c('PRE','POST','FOLLOW-UP'))
relab_genus_spread <- spread(relab_genus, Taxa, Relative_Abundance, sep = NULL)
write.table(relab_phylum_spread, file = '/Users/student05/Documents/relative abundance/relab_phylum.txt', sep= "\t", col.names = TRUE, row.names = FALSE)
write.table(relab_genus_spread, file = '/Users/student05/Documents/relative abundance/relab_genus.txt', sep ="\t", col.names = TRUE, row.names = FALSE)
relab_phylum_spread <- read.table("/Users/student05/Documents/relative abundance/relab_phylum.txt", sep = '\t', comment='',
head=T)
relab_genus_spread <- read.table("/Users/student05/Documents/relative abundance/relab_genus.txt", sep = '\t', comment='',
head=T)
Synchonisieren der Metadatensets und Laden der FA-Metadaten
relab_phylum_ID <- relab_phylum_spread
relab_phylum_ID <- mutate(relab_phylum_ID, SampleID = paste(Proband, Time,sep="."))
row.names(relab_phylum_ID) <- relab_phylum_ID$SampleID
relab_genus_ID <- relab_genus_spread
relab_genus_ID <- mutate(relab_genus_ID, SampleID = paste(Proband, Time, sep ="."))
row.names(relab_genus_ID) <- relab_genus_ID$SampleID
FA_stool <- read.table("/Users/student05/Documents/fa feces/Fa.feces.2.txt", sep = '\t', comment='',
head=T)
FA_stool$Time <-factor(FA_stool$Time, levels = c("PRE", "POST", "FOLLOW-UP"))
FA_stool <- subset(filter(FA_stool, !Time == "FOLLOW-UP"))
FA_stool <- subset(filter(FA_stool, !Proband == "31KE", !Proband == "34WF",
!Proband == "45GL", !Proband == "49RJ", !Proband == "54SL", !Proband == "74SA"))
FA_stool <- mutate(FA_stool, SampleID1 = paste(Proband, Time, sep = "."))
row.names(FA_stool) <- FA_stool$SampleID
common.ids.relab <- intersect(rownames(FA_stool), rownames(relab_phylum_ID))
FA_stool <- FA_stool[common.ids.relab,]
relab_phylum_ID <- relab_phylum_ID[common.ids.relab,]
relab_genus_ID <- relab_genus_ID[common.ids.relab,]
write.table(FA_stool, file = '/Users/student05/Documents/fa feces/FA fecal/relative abundance/FA_stool_total.txt', sep= "\t", col.names = TRUE, row.names = FALSE)
Erstellen des Phylum-Datensets und hinzufuegen des Log und Pseudocounts 0.00001
phylum_colnames <- colnames(relab_phylum_spread[, c(3:8)])
relab_phylum_ID <- relab_phylum_ID[,c(3:8)]+ 0.00001
relab_phylum_ID_log <- log10(relab_phylum_ID_log)
phylum_FA <- cbind(relab_phylum_ID, FA_stool[, c(1:19)])
phylum_FA$Time <- factor(phylum_FA$Time, levels = c("PRE", "POST"))
Loop fuer Korrelation zwischen gesaettigten FA und Phylum-Level
corr_map_phylum_sat <- filter(phylum_FA, !is.na(sat))
corr_spearman_Phylum_sat <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_sat, !is.na(i))
y = tmp[,i]
x = tmp$sat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$sat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$sat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_sat)+1
corr_spearman_Phylum_sat[nrow,"FA"] <- "sat"
corr_spearman_Phylum_sat[nrow, "Phylum"] = i
corr_spearman_Phylum_sat[nrow, "p.value"] = p
corr_spearman_Phylum_sat[nrow, "rho"] = rho
corr_spearman_Phylum_sat[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_sat[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_sat[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_sat[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_sat$p.adjusted <- p.adjust(corr_spearman_Phylum_sat$p.value, method = "BH", n = 35)
corr_spearman_Phylum_sat$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_sat$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_sat$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_sat$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_sat <- filter(corr_spearman_Phylum_sat, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_sat, file = '/Users/student05/Documents/fa feces/tabellen/sat.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten der gesaettigten FA und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=sat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Saturated fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time, scales="free_x")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(phylum_FA, x='sat', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Proteobacteria')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(phylum_FA, x='sat', y='k__Bacteria.p__Proteobacteria', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0, -1.7), cor.coef.size = 6, xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Proteobacteria')+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=0, hjust=1))
ggscatter(phylum_FA, x='sat', y='k__Bacteria.p__Verrucomicrobia', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord =c(250, -1), xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_FA, x='sat', y='k__Bacteria.p__Firmicutes', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord =c(250, -0.75), xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance p__Firmicutes')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
stat_cor(method = "pearson", label.x = 3, label.y = 30)
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=sat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Saturated fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=sat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Saturated fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=sat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Saturated fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)
in Arbeit
pdf("/Users/student05/Documents/fertige Plots/sat.verru.pdf",width=8, height=10)
ggscatter(phylum_FA, x='sat', y='k__Bacteria.p__Verrucomicrobia', palette = c('tomato', 'yellowgreen'), add = 'reg.line',color = "grey59",fill = "lightgray", conf.int = TRUE,
cor.coef = TRUE, cor.method = '',cor.coef.size = 8,xlab= 'Gesättigte Fettsäurenkonzentrationen [nmol/g]', ylab = 'Relatives Vorkommen p__Verrucomicrobia [%]')+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
geom_point(color='black', size=2.5)+
scale_y_log10(labels = percent_format())
dev.off()
pdf("/Users/student05/Documents/fertige Plots/sat.bacteroidetes.pdf",width=8, height=10)
ggscatter(phylum_FA, x='sat', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('skyblue', 'orchid'), add = 'reg.line', size = 2.5,conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord =c(0, -0.8),cor.coef.size = 7, xlab= 'Gesättigte Fettsäurenkonzentrationen [nmol/g]', ylab = 'Relatives Vorkommen p__Bacteroidetes [%]')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(hjust=1))+
scale_y_log10(labels = percent_format())
dev.off()
pdf("/Users/student05/Documents/fertige Plots/unsat.bacteroidetes.pdf",width=8, height=10)
ggscatter(phylum_FA, x='unsat', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('skyblue', 'orchid'), add = 'reg.line', size = 2.5,conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord =c(0, -0.8),cor.coef.size = 7, xlab= 'Ungesättigte Fettsäurenkonzentrationen [nmol/g]', ylab = 'Relatives Vorkommen p__Bacteroidetes [%]')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(hjust=1))+
scale_y_log10(labels = percent_format())
dev.off()
pdf("/Users/student05/Documents/fertige Plots/omega3.bacteroidetes.neu.pdf",width=8, height=10)
ggscatter(phylum_FA, x='Omega3', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('skyblue', 'orchid'), add = 'reg.line', size = 2.5,conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord =c(0, -0.8),cor.coef.size = 7, xlab= 'Ungesättigte Fettsäurenkonzentrationen [nmol/g]', ylab = 'Relatives Vorkommen p__Bacteroidetes [%]')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(hjust=1))+
scale_y_log10(labels = percent_format())
dev.off()
pdf("/Users/student05/Documents/fertige Plots/sat.akkermansia.pdf",width=8, height=10)
ggscatter(genus_FA, x='sat', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia', palette = c('tomato', 'yellowgreen'), add = 'reg.line',color = "grey59",fill = "lightgray", conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0, -0.8),cor.coef.size = 8, xlab= 'Gesättigte Fettsäurenkonzentrationen [nmol/g]', ylab = 'log10 (Relatives Vorkommen g__Akkermansia)')+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")+
geom_point(color='grey52')
dev.off()
Loop einfach ungesaettigte FA und Phylum-Level
corr_map_phylum_mono.unsat <- filter(phylum_FA, !is.na(mono.unsat))
corr_spearman_Phylum_mono.unsat <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_mono.unsat, !is.na(i))
y = tmp[,i]
x = tmp$mono.unsat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$mono.unsat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$mono.unsat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_mono.unsat)+1
corr_spearman_Phylum_mono.unsat[nrow,"FA"] <- "mono.unsat"
corr_spearman_Phylum_mono.unsat[nrow, "Phylum"] = i
corr_spearman_Phylum_mono.unsat[nrow, "p.value"] = p
corr_spearman_Phylum_mono.unsat[nrow, "rho"] = rho
corr_spearman_Phylum_mono.unsat[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_mono.unsat[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_mono.unsat[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_mono.unsat[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_mono.unsat$p.adjusted <- p.adjust(corr_spearman_Phylum_mono.unsat$p.value, method = "BH", n = 35)
corr_spearman_Phylum_mono.unsat$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_mono.unsat$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_mono.unsat$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_mono.unsat$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_mono.unsat <- filter(corr_spearman_Phylum_sat, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_mono.unsat, file = '/Users/student05/Documents/fa feces/tabellen/mono.unsat.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von einfach ungesaettigten FA und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=mono.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Monounsaturated fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_FA, x='mono.unsat', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Monounsaturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance p__Proteobacteria')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=mono.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Monounsaturated fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(phylum_FA, x='mono.unsat', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Monounsaturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Actinobacteria')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop zweifach ungesaettigten FA und phylum-level
corr_map_phylum_more.2.unsat <- filter(phylum_FA, !is.na(more.2.unsat))
corr_spearman_Phylum_more.2.unsat <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_more.2.unsat, !is.na(i))
y = tmp[,i]
x = tmp$more.2.unsat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$more.2.unsat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$more.2.unsat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_more.2.unsat)+1
corr_spearman_Phylum_more.2.unsat[nrow,"FA"] <- "> 2 unsat"
corr_spearman_Phylum_more.2.unsat[nrow, "Phylum"] = i
corr_spearman_Phylum_more.2.unsat[nrow, "p.value"] = p
corr_spearman_Phylum_more.2.unsat[nrow, "rho"] = rho
corr_spearman_Phylum_more.2.unsat[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_more.2.unsat[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_more.2.unsat[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_more.2.unsat[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_more.2.unsat$p.adjusted <- p.adjust(corr_spearman_Phylum_more.2.unsat$p.value, method = "BH", n = 35)
corr_spearman_Phylum_more.2.unsat$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_more.2.unsat$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_more.2.unsat$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_more.2.unsat$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_more.2.unsat <- filter(corr_spearman_Phylum_more.2.unsat, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_more.2.unsat, file = '/Users/student05/Documents/fa feces/tabellen/more.2.unsat.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von zweifach ungesaettigten FA und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=more.2.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Diunsaturated fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=more.2.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Diunsaturated fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
geom_text(aes(label=Proband),hjust=0, vjust=0)
ggscatter(phylum_FA, x='more.2.unsat', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '> 2 unsaturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance p__Bacteroidetes')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(phylum_FA, x='more.2.unsat', y='k__Bacteria.p__Bacteroidetes', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '> 2 unsaturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance p__Bacteroidetes')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=more.2.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Diunsaturated fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop weniger 14C und phylum-level
corr_map_phylum_less.14 <- filter(phylum_FA, !is.na(less.14))
corr_spearman_Phylum_less.14 <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_less.14, !is.na(i))
y = tmp[,i]
x = tmp$less.14
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$less.14
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$less.14
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_less.14)+1
corr_spearman_Phylum_less.14[nrow,"FA"] <- "< 14 c"
corr_spearman_Phylum_less.14[nrow, "Phylum"] = i
corr_spearman_Phylum_less.14[nrow, "p.value"] = p
corr_spearman_Phylum_less.14[nrow, "rho"] = rho
corr_spearman_Phylum_less.14[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_less.14[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_less.14[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_less.14[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_less.14$p.adjusted <- p.adjust(corr_spearman_Phylum_less.14$p.value, method = "BH", n = 35)
corr_spearman_Phylum_less.14$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_less.14$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_less.14$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_less.14$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_less.14 <- filter(corr_spearman_Phylum_less.14, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_less.14, file = '/Users/student05/Documents/fa feces/tabellen/less.14.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten FA mit weniger als 14C atome und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=less.14)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('< 14 c-atoms fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
geom_text(aes(label=Proband),hjust=0, vjust=0)
ggscatter(phylum_FA, x='less.14', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Less 14c fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Proteobacteria')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop C14-17 FA und phylum-level
corr_map_phylum_c14.17 <- filter(phylum_FA, !is.na(c14.17 ))
corr_spearman_Phylum_c14.17 <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_c14.17 , !is.na(i))
y = tmp[,i]
x = tmp$c14.17
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$c14.17
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$c14.17
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_c14.17 )+1
corr_spearman_Phylum_c14.17 [nrow,"FA"] <- "c 14-17"
corr_spearman_Phylum_c14.17 [nrow, "Phylum"] = i
corr_spearman_Phylum_c14.17 [nrow, "p.value"] = p
corr_spearman_Phylum_c14.17 [nrow, "rho"] = rho
corr_spearman_Phylum_c14.17 [nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_c14.17 [nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_c14.17 [nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_c14.17 [nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_c14.17 $p.adjusted <- p.adjust(corr_spearman_Phylum_c14.17 $p.value, method = "BH", n = 35)
corr_spearman_Phylum_c14.17 $p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_c14.17 $p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_c14.17 $p.adjusted_POST <- p.adjust(corr_spearman_Phylum_c14.17 $p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_c14.17 <- filter(corr_spearman_Phylum_c14.17, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_c14.17, file = '/Users/student05/Documents/fa feces/tabellen/c14.17.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten C14-17 FA und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('14-17 c-atoms fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(phylum_FA, x='c14.17', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c 14-17 fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Proteobacteria')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('< 14-17 c-atoms fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('< 14-17 c-atoms fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('< 14-17 c-atoms fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(phylum_FA, x='c14.17', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord =c(150, -0.7), xlab= 'c 14-17 fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance p__Firmicutes')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_FA, x='c14.17', y='k__Bacteria.p__Firmicutes', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord =c(150, -0.7), xlab= 'c 14-17 fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance p__Firmicutes')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
Loop C18 FA und phylum-level
orr_map_phylum_c18.19 <- filter(phylum_FA, !is.na(c18 ))
corr_spearman_Phylum_c18.19 <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_c18.19 , !is.na(i))
y = tmp[,i]
x = tmp$c18
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$c18
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$c18
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_c18.19 )+1
corr_spearman_Phylum_c18.19 [nrow,"FA"] <- "c 18-19"
corr_spearman_Phylum_c18.19 [nrow, "Phylum"] = i
corr_spearman_Phylum_c18.19 [nrow, "p.value"] = p
corr_spearman_Phylum_c18.19 [nrow, "rho"] = rho
corr_spearman_Phylum_c18.19 [nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_c18.19 [nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_c18.19 [nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_c18.19 [nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_c18.19 $p.adjusted <- p.adjust(corr_spearman_Phylum_c18.19 $p.value, method = "BH", n = 35)
corr_spearman_Phylum_c18.19 $p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_c18.19 $p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_c18.19 $p.adjusted_POST <- p.adjust(corr_spearman_Phylum_c18.19 $p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_c18.19 <- filter(corr_spearman_Phylum_c18.19, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_c18.19, file = '/Users/student05/Documents/fa feces/tabellen/c18.19.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von C18 FA und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=c18.19)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('18-19 c-atoms fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=c18.19)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('< 18-19 c-atoms fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=c18.19)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('< 14-17 c-atoms fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(phylum_FA, x='c18.19', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c 18-19 fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Verrucomicrobia')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop C20-24 und phylum-level
corr_map_phylum_c20.24 <- filter(phylum_FA, !is.na(c20.24 ))
corr_spearman_Phylum_c20.24 <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_c20.24 , !is.na(i))
y = tmp[,i]
x = tmp$c20.24
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$c20.24
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$c20.24
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_c20.24 )+1
corr_spearman_Phylum_c20.24 [nrow,"FA"] <- "c 20-24"
corr_spearman_Phylum_c20.24 [nrow, "Phylum"] = i
corr_spearman_Phylum_c20.24 [nrow, "p.value"] = p
corr_spearman_Phylum_c20.24 [nrow, "rho"] = rho
corr_spearman_Phylum_c20.24 [nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_c20.24 [nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_c20.24 [nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_c20.24 [nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_c20.24$p.adjusted <- p.adjust(corr_spearman_Phylum_c20.24$p.value, method = "BH", n = 35)
corr_spearman_Phylum_c20.24$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_c20.24$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_c20.24$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_c20.24$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_c20.24 <- filter(corr_spearman_Phylum_c20.24, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_c20.24, file = '/Users/student05/Documents/fa feces/tabellen/c20.24.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von C20-24 und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('20-21 c-atoms fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('< 18-19 c-atoms fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('20-21 c-atoms fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(phylum_FA, x='c20.21', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c 20-21 fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Tenericutes, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('20-21 c-atoms fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(phylum_FA, x='c20.21', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c 20-21 fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Tenericutes')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop total FA und phylum-level
corr_map_phylum_total <- filter(phylum_FA, !is.na(total ))
corr_spearman_Phylum_total <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_total , !is.na(i))
y = tmp[,i]
x = tmp$total
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$total
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$total
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_total )+1
corr_spearman_Phylum_total [nrow,"FA"] <- "total"
corr_spearman_Phylum_total [nrow, "Phylum"] = i
corr_spearman_Phylum_total [nrow, "p.value"] = p
corr_spearman_Phylum_total [nrow, "rho"] = rho
corr_spearman_Phylum_total [nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_total [nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_total [nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_total [nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_total $p.adjusted <- p.adjust(corr_spearman_Phylum_total $p.value, method = "BH", n = 35)
corr_spearman_Phylum_total $p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_total $p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_total $p.adjusted_POST <- p.adjust(corr_spearman_Phylum_total $p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_total <- filter(corr_spearman_Phylum_total, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_total, file = '/Users/student05/Documents/fa feces/tabellen/total.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von total FA und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(phylum_FA, x='total', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Total fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance p__Proteobacteria')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(phylum_FA, x='total', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Total fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Actinobacteria')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Firmicutes, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Tenericutes, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(phylum_FA, x='c20.21', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c 20-21 fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Tenericutes')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop Omega3 und phylum-level
corr_map_phylum_Omega3 <- filter(phylum_FA, !is.na(Omega3 ))
corr_spearman_Phylum_Omega3 <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_Omega3 , !is.na(i))
y = tmp[,i]
x = tmp$Omega3
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Omega3
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Omega3
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_Omega3 )+1
corr_spearman_Phylum_Omega3 [nrow,"FA"] <- "Omega3"
corr_spearman_Phylum_Omega3 [nrow, "Phylum"] = i
corr_spearman_Phylum_Omega3 [nrow, "p.value"] = p
corr_spearman_Phylum_Omega3 [nrow, "rho"] = rho
corr_spearman_Phylum_Omega3 [nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_Omega3 [nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_Omega3[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_Omega3[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_Omega3$p.adjusted <- p.adjust(corr_spearman_Phylum_Omega3$p.value, method = "BH", n = 35)
corr_spearman_Phylum_Omega3$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_Omega3$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_Omega3$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_Omega3$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_Omega3<- filter(corr_spearman_Phylum_Omega3, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_Omega3, file = '/Users/student05/Documents/fa feces/tabellen/Omega3.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten Omega3 und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=Omega3)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Firmicutes, x=Omega3)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=Omega3)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
pdf("/Users/student05/Documents/fertige Plots/Linolsäure.bacteroidetes.pdf",width=8, height=10)
ggscatter(phylum_FA, x='Omega3', y='k__Bacteria.p__Bacteroidetes',color = 'Time', label = 'Proband',palette = c('skyblue', 'orchid'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(0, -0.9), cor.coef.size = 7,xlab= 'Fäkale alpha-Linolensäure Konzentrationen [nmol/g]', ylab = 'log10 (Relatives Vorkommen p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
dev.off()
Loop Omega 6 und Phylum-level
corr_map_phylum_Omega6 <- filter(phylum_FA, !is.na(Omega6 ))
corr_spearman_Phylum_Omega6 <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_Omega6 , !is.na(i))
y = tmp[,i]
x = tmp$Omega6
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Omega6
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Omega6
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_Omega6 )+1
corr_spearman_Phylum_Omega6 [nrow,"FA"] <- "Omega6"
corr_spearman_Phylum_Omega6 [nrow, "Phylum"] = i
corr_spearman_Phylum_Omega6 [nrow, "p.value"] = p
corr_spearman_Phylum_Omega6 [nrow, "rho"] = rho
corr_spearman_Phylum_Omega6 [nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_Omega6 [nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_Omega6 [nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_Omega6 [nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_Omega6 $p.adjusted <- p.adjust(corr_spearman_Phylum_Omega6 $p.value, method = "BH", n = 35)
corr_spearman_Phylum_Omega6 $p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_Omega6 $p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_Omega6 $p.adjusted_POST <- p.adjust(corr_spearman_Phylum_Omega6 $p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_Omega6 <- filter(corr_spearman_Phylum_Omega6, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_Omega6, file = '/Users/student05/Documents/fa feces/tabellen/Omega6.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten omega6 und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=Omega6)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Firmicutes, x=Omega6)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=Omega6)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=Linolsaeure_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=Linolsaeure_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)+
theme(legend.position="top")
Loop omega6/omega3-ratio und phylum-level
corr_map_phylum_ratio <- filter(phylum_FA, !is.na(ratio))
corr_spearman_Phylum_ratio <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_ratio , !is.na(i))
y = tmp[,i]
x = tmp$ratio
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$ratio
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$ratio
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_ratio )+1
corr_spearman_Phylum_ratio [nrow,"FA"] <- "ratio"
corr_spearman_Phylum_ratio [nrow, "Phylum"] = i
corr_spearman_Phylum_ratio [nrow, "p.value"] = p
corr_spearman_Phylum_ratio [nrow, "rho"] = rho
corr_spearman_Phylum_ratio [nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_ratio [nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_ratio [nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_ratio [nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_ratio $p.adjusted <- p.adjust(corr_spearman_Phylum_ratio $p.value, method = "BH", n = 35)
corr_spearman_Phylum_ratio $p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_ratio $p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_ratio $p.adjusted_POST <- p.adjust(corr_spearman_Phylum_ratio $p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_ratio <- filter(corr_spearman_Phylum_ratio, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_ratio, file = '/Users/student05/Documents/fa feces/tabellen/ratio.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von Omega6/omega3-ratio und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=ratio)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('omega 6/omega 3 ratio fecal') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=ratio)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('omega 6/omega 3 ratio fecal') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Firmicutes, x=ratio)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('omega 6/omega 3 ratio fecal') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=ratio)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('EPA intake [g]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=ratio)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('omega 6/omega 3 ratio fecal') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Tenericutes, x=ratio)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('DHA intake [g]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
Loop ungesaettigte FA und Phylum-level
corr_map_phylum_unsat <- filter(phylum_FA, !is.na(unsat))
corr_spearman_Phylum_unsat <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_unsat , !is.na(i))
y = tmp[,i]
x = tmp$unsat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$unsat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$unsat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_unsat )+1
corr_spearman_Phylum_unsat [nrow,"FA"] <- "unsat"
corr_spearman_Phylum_unsat [nrow, "Phylum"] = i
corr_spearman_Phylum_unsat [nrow, "p.value"] = p
corr_spearman_Phylum_unsat [nrow, "rho"] = rho
corr_spearman_Phylum_unsat [nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_unsat [nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_unsat [nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_unsat [nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_unsat $p.adjusted <- p.adjust(corr_spearman_Phylum_unsat $p.value, method = "BH", n = 35)
corr_spearman_Phylum_unsat $p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_unsat $p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_unsat $p.adjusted_POST <- p.adjust(corr_spearman_Phylum_unsat $p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_unsat <- filter(corr_spearman_Phylum_unsat, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_unsat, file = '/Users/student05/Documents/fa feces/tabellen/unsat.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Analysen zwischen FA und Genus-level Datensets filtern und hinzufuegen von log und pseudocount 0.00001
genus_colnames <- colnames(relab_genus_spread[, c(3:31)])
relab_genus_ID <- relab_genus_ID[,c(3:31)] + 0.00001
relab_genus_ID_log <- log10(relab_genus_ID_log)
genus_FA <- cbind(relab_genus_ID, FA_stool[, c(1:19)])
genus_FA$Time <- factor(genus_FA$Time, levels = c("PRE", "POST"))
Loop gesaettigte FA und genus-level
corr_map_genus_sat <- filter(genus_FA, !is.na(sat))
corr_spearman_genus_sat <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_sat, !is.na(i))
y = tmp[,i]
x = tmp$sat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$sat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$sat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_sat)+1
corr_spearman_genus_sat[nrow,"FA"] = "saturated"
corr_spearman_genus_sat[nrow, "Genus"] = i
corr_spearman_genus_sat[nrow, "p.value"] = p
corr_spearman_genus_sat[nrow, "rho"] = rho
corr_spearman_genus_sat[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_sat[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_sat[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_sat[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_sat$p.adjusted <- p.adjust(corr_spearman_genus_sat$p.value, method = "BH", n = 35)
corr_spearman_genus_sat$p.adjusted_PRE <- p.adjust(corr_spearman_genus_sat$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_sat$p.adjusted_POST <- p.adjust(corr_spearman_genus_sat$p.value_POST, method = "BH", n = 35)
corr_sig_genus_sat <- filter(corr_spearman_genus_sat, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_sat, file = '/Users/student05/Documents/fa feces/tabellen/sat.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
PLotten von gesaettigten FA und genus-level
ggscatter(genus_FA, x='sat', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(400, -1.3),cor.coef.size = 5, xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, x=sat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Saturated fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance g__Oscillospira)')+
facet_wrap(~Time)
ggscatter(genus_FA, x='sat', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='sat', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='sat', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, x=sat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Saturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bifidobacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella, x=sat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Saturated Concentration [nmol/mg]') +
ylab('log10 (Relative Abundance g__Collinsella)')+
facet_wrap(~Time)
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__, x=sat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab(' Concentration [mg/ml]') + ylab('log10 (Relative Abundance f__Erysipelotrichaceae)')+
facet_wrap(~Time)
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, x=sat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Saturated fatty acids Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Rikenellaceae)')+
facet_wrap(~Time)
ggscatter(genus_FA, x='sat', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance f__Rikenellaceae')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium, x=sat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Saturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Faecalibacterium )')+
facet_wrap(~Time)
ggplot(genus_FA, aes(y=k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, x=sat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Saturated fatt acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Akkermansia )')+
facet_wrap(~Time)
ggscatter(genus_FA, x='sat', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(400, -0.5), xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Akkermansia')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='sat', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(400, -0.5), xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Akkermansia')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='sat', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(500, -1), xlab= 'Saturated fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Akkermansia')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
in Arbeit
pdf("/Users/student05/Documents/fertige Plots/sat.faecali.pdf",width=8, height=10)
ggscatter(genus_FA, x='sat', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium', palette = c('tomato', 'yellowgreen'), add = 'reg.line',color = "grey59",fill = "lightgray", conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0, -1.3),cor.coef.size = 8, xlab= 'Gesättigte Fettsäurenkonzentrationen [nmol/g]', ylab = 'Relatives Vorkommen g__Faecalibacterium [%]')+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")+
geom_point(color='black', size=2.5)+
scale_y_log10(labels = percent_format())
dev.off()
pdf("/Users/student05/Documents/fertige Plots/sat.oscillo.pdf",width=8, height=10)
ggscatter(genus_FA, x='sat', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira', palette = c('tomato', 'yellowgreen'), add = 'reg.line',color = "grey59",fill = "lightgray", conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0, -2),cor.coef.size = 8, xlab= 'Gesättigte Fettsäurenkonzentrationen [nmol/g]', ylab = 'Relatives Vorkommen g__Oscillospira [%]')+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")+
geom_point(color='black', size=2.5)+
scale_y_log10(labels = percent_format())
dev.off()
pdf("/Users/student05/Documents/fertige Plots/sat.akkermansia.pdf",width=8, height=10)
ggscatter(genus_FA, x='sat', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia', palette = c('tomato', 'yellowgreen'), add = 'reg.line',color = "grey59",fill = "lightgray", conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0, -0.7),cor.coef.size = 8, xlab= 'Gesättigte Fettsäurenkonzentrationen [nmol/g]', ylab ='Relatives Vorkommen g__Akkermansia [%]')+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")+
geom_point(color='black', size=2.5)+
scale_y_log10(labels = percent_format())
dev.off()
Loop einfach ungesaettigte FA und genus-level
corr_map_genus_mono.unsat <- filter(genus_FA, !is.na(mono.unsat))
corr_spearman_genus_mono.unsat <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_mono.unsat, !is.na(i))
y = tmp[,i]
x = tmp$mono.unsat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$mono.unsat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$mono.unsat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_mono.unsat)+1
corr_spearman_genus_mono.unsat[nrow,"FA"] = "mono.unsaturated"
corr_spearman_genus_mono.unsat[nrow, "Genus"] = i
corr_spearman_genus_mono.unsat[nrow, "p.value"] = p
corr_spearman_genus_mono.unsat[nrow, "rho"] = rho
corr_spearman_genus_mono.unsat[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_mono.unsat[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_mono.unsat[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_mono.unsat[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_mono.unsat$p.adjusted <- p.adjust(corr_spearman_genus_mono.unsat$p.value, method = "BH", n = 35)
corr_spearman_genus_mono.unsat$p.adjusted_PRE <- p.adjust(corr_spearman_genus_mono.unsat$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_mono.unsat$p.adjusted_POST <- p.adjust(corr_spearman_genus_mono.unsat$p.value_POST, method = "BH", n = 35)
corr_sig_genus_mono.unsat <- filter(corr_spearman_genus_mono.unsat, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_mono.unsat, file = '/Users/student05/Documents/fa feces/tabellen/mono.unsat.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von einfach ungesaettigten FA und genus-level
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, x=mono.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('mono.unsaturated fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance g__Oscillospira)')+
facet_wrap(~Time)
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, x=mono.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('mono.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bifidobacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, x=mono.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('mono.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bacteroides)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella, x=mono.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('mono.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Sutterella)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella, x=mono.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('mono.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Prevotella)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella, x=mono.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('mono.unsaturated Concentration [nmol/mg]') +
ylab('log10 (Relative Abundance g__Collinsella)')+
facet_wrap(~Time)
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__, x=mono.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab(' Concentration [mg/ml]') + ylab('log10 (Relative Abundance f__Erysipelotrichaceae)')+
facet_wrap(~Time)
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, x=mono.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('mono.unsaturated fatty acids Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Rikenellaceae)')+
facet_wrap(~Time)
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium, x=mono.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('mono.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Faecalibacterium )')+
facet_wrap(~Time)
ggplot(genus_FA, aes(y=k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, x=mono.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('mono.unsaturated fatt acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Akkermansia )')+
facet_wrap(~Time)
Loop zweifach ungesaettigte FA und genus-level
corr_map_genus_di.unsat <- filter(genus_FA, !is.na(di.unsat))
corr_spearman_genus_di.unsat <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_di.unsat, !is.na(i))
y = tmp[,i]
x = tmp$di.unsat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$di.unsat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$di.unsat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_di.unsat)+1
corr_spearman_genus_di.unsat[nrow,"FA"] = "di.unsaturated"
corr_spearman_genus_di.unsat[nrow, "Genus"] = i
corr_spearman_genus_di.unsat[nrow, "p.value"] = p
corr_spearman_genus_di.unsat[nrow, "rho"] = rho
corr_spearman_genus_di.unsat[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_di.unsat[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_di.unsat[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_di.unsat[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_di.unsat$p.adjusted <- p.adjust(corr_spearman_genus_di.unsat$p.value, method = "BH", n = 35)
corr_spearman_genus_di.unsat$p.adjusted_PRE <- p.adjust(corr_spearman_genus_di.unsat$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_di.unsat$p.adjusted_POST <- p.adjust(corr_spearman_genus_di.unsat$p.value_POST, method = "BH", n = 35)
corr_sig_genus_di.unsat <- filter(corr_spearman_genus_di.unsat, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_di.unsat, file = '/Users/student05/Documents/fa feces/tabellen/di.unsat.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
PLotten von zweifach ungesaettigten FAs und genus-level
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, x=di.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('di.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bifidobacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, x=di.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('di.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bacteroides)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella, x=di.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('di.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Sutterella)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea, x=di.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('di.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Dorea)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister, x=di.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('di.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Dialister)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop mehr als zweifach ungesaettigte FAs und genus-level
corr_map_genus_more.2.unsat <- filter(genus_FA, !is.na(more.2.unsat))
corr_spearman_genus_more.2.unsat <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_more.2.unsat, !is.na(i))
y = tmp[,i]
x = tmp$more.2.unsat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$more.2.unsat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$more.2.unsat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_more.2.unsat)+1
corr_spearman_genus_more.2.unsat[nrow,"FA"] = "more.2.unsaturated"
corr_spearman_genus_more.2.unsat[nrow, "Genus"] = i
corr_spearman_genus_more.2.unsat[nrow, "p.value"] = p
corr_spearman_genus_more.2.unsat[nrow, "rho"] = rho
corr_spearman_genus_more.2.unsat[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_more.2.unsat[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_more.2.unsat[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_more.2.unsat[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_more.2.unsat$p.adjusted <- p.adjust(corr_spearman_genus_more.2.unsat$p.value, method = "BH", n = 35)
corr_spearman_genus_more.2.unsat$p.adjusted_PRE <- p.adjust(corr_spearman_genus_more.2.unsat$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_more.2.unsat$p.adjusted_POST <- p.adjust(corr_spearman_genus_more.2.unsat$p.value_POST, method = "BH", n = 35)
corr_sig_genus_more.2.unsat <- filter(corr_spearman_genus_more.2.unsat, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_more.2.unsat, file = '/Users/student05/Documents/fa feces/tabellen/more.2.unsat.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von mehr als zweifach ungesaettigten FA und genus-level
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella, x=more.2.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('more.2.unsaturated fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance g__Oscillospira)')+
facet_wrap(~Time) +
theme(text = element_text(size=12),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, x=more.2.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('more.2.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bifidobacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, x=more.2.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('more.2.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bacteroides)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella, x=more.2.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('more.2.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Sutterella)')+
facet_wrap(~Time)+
theme(text = element_text(size=12),
axis.text.x = element_text(angle=60, hjust=1))+
geom_text(aes(label=Proband),hjust=0, vjust=0)
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella, x=more.2.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('more.2.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Collinsella)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister, x=more.2.unsat)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('more.2.unsaturated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Dialister)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop FA weniger als 14C und genus-level
corr_map_genus_less.14 <- filter(genus_FA, !is.na(less.14))
corr_spearman_genus_less.14 <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_less.14, !is.na(i))
y = tmp[,i]
x = tmp$less.14
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$less.14
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$less.14
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_less.14)+1
corr_spearman_genus_less.14[nrow,"FA"] = "less.14"
corr_spearman_genus_less.14[nrow, "Genus"] = i
corr_spearman_genus_less.14[nrow, "p.value"] = p
corr_spearman_genus_less.14[nrow, "rho"] = rho
corr_spearman_genus_less.14[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_less.14[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_less.14[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_less.14[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_less.14$p.adjusted <- p.adjust(corr_spearman_genus_less.14$p.value, method = "BH", n = 35)
corr_spearman_genus_less.14$p.adjusted_PRE <- p.adjust(corr_spearman_genus_less.14$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_less.14$p.adjusted_POST <- p.adjust(corr_spearman_genus_less.14$p.value_POST, method = "BH", n = 35)
corr_sig_genus_less.14 <- filter(corr_spearman_genus_less.14, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_less.14, file = '/Users/student05/Documents/fa feces/tabellen/less.14.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten weniger als 14C FA und genus-level
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, x=less.14)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('less.14urated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bifidobacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, x=less.14)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('> 14 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bacteroides)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella, x=less.14)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('less.14urated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Sutterella)')+
facet_wrap(~Time)+
theme(text = element_text(size=12),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella, x=less.14)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('> 14 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Collinsella)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium., x=less.14)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('> 14 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Eubacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella, x=less.14)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('> 14 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Prevotella)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium, x=less.14)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('> 14 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Faecalibacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium., x=less.14)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('> 14 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Eubacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop C14-17 FA und genus-level
corr_map_genus_c14.17 <- filter(genus_FA, !is.na(c14.17))
corr_spearman_genus_c14.17 <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_c14.17, !is.na(i))
y = tmp[,i]
x = tmp$c14.17
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$c14.17
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$c14.17
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_c14.17)+1
corr_spearman_genus_c14.17[nrow,"FA"] = "c14.17"
corr_spearman_genus_c14.17[nrow, "Genus"] = i
corr_spearman_genus_c14.17[nrow, "p.value"] = p
corr_spearman_genus_c14.17[nrow, "rho"] = rho
corr_spearman_genus_c14.17[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_c14.17[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_c14.17[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_c14.17[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_c14.17$p.adjusted <- p.adjust(corr_spearman_genus_c14.17$p.value, method = "BH", n = 35)
corr_spearman_genus_c14.17$p.adjusted_PRE <- p.adjust(corr_spearman_genus_c14.17$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_c14.17$p.adjusted_POST <- p.adjust(corr_spearman_genus_c14.17$p.value_POST, method = "BH", n = 35)
corr_sig_genus_c14.17 <- filter(corr_spearman_genus_c14.17, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_c14.17, file = '/Users/student05/Documents/fa feces/tabellen/c14.17.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von C14-17 FA und genus-level
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('c 14-17 fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance g__Oscillospira)')+
facet_wrap(~Time) +
theme(text = element_text(size=12),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('c 14-17 fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bifidobacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('> 14 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bacteroides)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('c14.17urated fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Sutterella)')+
facet_wrap(~Time)+
theme(text = element_text(size=12),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab(' 14-17 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Collinsella)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('14-17 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Akkermansia)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('c 14-17 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Faecalibacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('14-17 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Rikenellaceae)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
genus_FA$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__.Barnesiellaceae..g__
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__.Barnesiellaceae..g__, x=c14.17)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('14-17 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Barnesiellaceae)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='c14.17', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c 14-17 fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='c14.17', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c 14-17 fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Loop C18 FA und genus-level
corr_map_genus_c18 <- filter(genus_FA, !is.na(c18))
corr_spearman_genus_c18 <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_c18, !is.na(i))
y = tmp[,i]
x = tmp$c18
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$c18
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$c18
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_c18)+1
corr_spearman_genus_c18[nrow,"FA"] = "c18"
corr_spearman_genus_c18[nrow, "Genus"] = i
corr_spearman_genus_c18[nrow, "p.value"] = p
corr_spearman_genus_c18[nrow, "rho"] = rho
corr_spearman_genus_c18[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_c18[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_c18[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_c18[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_c18$p.adjusted <- p.adjust(corr_spearman_genus_c18$p.value, method = "BH", n = 35)
corr_spearman_genus_c18$p.adjusted_PRE <- p.adjust(corr_spearman_genus_c18$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_c18$p.adjusted_POST <- p.adjust(corr_spearman_genus_c18$p.value_POST, method = "BH", n = 35)
corr_sig_genus_c18 <- filter(corr_spearman_genus_c18, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_c18, file = '/Users/student05/Documents/fa feces/tabellen/c18.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten C18 FA und genus-level
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, x=c18.19)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('c 18 fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance g__Oscillospira)')+
facet_wrap(~Time) +
theme(text = element_text(size=12),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, x=c18.19)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('c 18 fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bifidobacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, x=c18.19)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('18 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bacteroides)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella, x=c18.19)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('18 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Sutterella)')+
facet_wrap(~Time)+
theme(text = element_text(size=12),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__, x=c18.19)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('18 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Ruminococcaceae)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, x=c18.19)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('18 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Akkermansia)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium, x=c18.19)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('c 18 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Faecalibacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, x=c18.19)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('18 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Rikenellaceae)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__.Barnesiellaceae..g__, x=c18.19)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('18 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Barnesiellaceae)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop C20-24 FA und genus-level
corr_map_genus_c20.24 <- filter(genus_FA, !is.na(c20.24))
corr_spearman_genus_c20.24 <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_c20.24, !is.na(i))
y = tmp[,i]
x = tmp$c20.24
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$c20.24
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$c20.24
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_c20.24)+1
corr_spearman_genus_c20.24[nrow,"FA"] = "c20.24"
corr_spearman_genus_c20.24[nrow, "Genus"] = i
corr_spearman_genus_c20.24[nrow, "p.value"] = p
corr_spearman_genus_c20.24[nrow, "rho"] = rho
corr_spearman_genus_c20.24[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_c20.24[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_c20.24[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_c20.24[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_c20.24$p.adjusted <- p.adjust(corr_spearman_genus_c20.24$p.value, method = "BH", n = 35)
corr_spearman_genus_c20.24$p.adjusted_PRE <- p.adjust(corr_spearman_genus_c20.24$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_c20.24$p.adjusted_POST <- p.adjust(corr_spearman_genus_c20.24$p.value_POST, method = "BH", n = 35)
corr_sig_genus_c20.24 <- filter(corr_spearman_genus_c20.24, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_c20.24, file = '/Users/student05/Documents/fa feces/tabellen/c20.24.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von C20-24 FA und genus-level
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('c 20-24 fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance g__Oscillospira)')+
facet_wrap(~Time) +
theme(text = element_text(size=12),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='c20.21', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c 20-24 fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('c 20-24 fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bifidobacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('20-24 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bacteroides)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('20-24 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Sutterella)')+
facet_wrap(~Time)+
theme(text = element_text(size=12),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('20-24 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Ruminococcaceae)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('20-24 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Akkermansia)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('c 20-24 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Faecalibacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='c20.21', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'c 20-24 fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('20-24 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Rikenellaceae)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__.Barnesiellaceae..g__, x=c20.21)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('20-24 c-atoms fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Barnesiellaceae)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop total FA und genus-level
corr_map_genus_total <- filter(genus_FA, !is.na(total))
corr_spearman_genus_total <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_total, !is.na(i))
y = tmp[,i]
x = tmp$total
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$total
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$total
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_total)+1
corr_spearman_genus_total[nrow,"FA"] = "total"
corr_spearman_genus_total[nrow, "Genus"] = i
corr_spearman_genus_total[nrow, "p.value"] = p
corr_spearman_genus_total[nrow, "rho"] = rho
corr_spearman_genus_total[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_total[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_total[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_total[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_total$p.adjusted <- p.adjust(corr_spearman_genus_total$p.value, method = "BH", n = 35)
corr_spearman_genus_total$p.adjusted_PRE <- p.adjust(corr_spearman_genus_total$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_total$p.adjusted_POST <- p.adjust(corr_spearman_genus_total$p.value_POST, method = "BH", n = 35)
corr_sig_genus_total <- filter(corr_spearman_genus_total, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_total, file = '/Users/student05/Documents/fa feces/tabellen/total.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von total FA und genus-level
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g]') +
ylab('log10 (Relative Abundance g__Oscillospira)')+
facet_wrap(~Time) +
theme(text = element_text(size=12),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bifidobacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='total', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Total fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Bacteroides)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Sutterella)')+
facet_wrap(~Time)+
theme(text = element_text(size=12),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='total', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Total fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Ruminococcaceae)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Akkermansia)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__Faecalibacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Rikenellaceae)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='total', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Total fatty acid Concentration [nmol/g]', ylab = 'log10 (Relative Abundance f__Rikenellaceae')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(genus_FA, aes(y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__.Barnesiellaceae..g__, x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance f__Barnesiellaceae)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus., x=total)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('total fatty acid Concentration [nmol/g DW]') +
ylab('log10 (Relative Abundance g__.Ruminococcus)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop Omega3 FA und genus-level
corr_map_genus_Omega3 <- filter(genus_FA, !is.na(Omega3))
corr_spearman_genus_Omega3 <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_Omega3, !is.na(i))
y = tmp[,i]
x = tmp$Omega3
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Omega3
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Omega3
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_Omega3)+1
corr_spearman_genus_Omega3[nrow,"FA"] = "Omega3"
corr_spearman_genus_Omega3[nrow, "Genus"] = i
corr_spearman_genus_Omega3[nrow, "p.value"] = p
corr_spearman_genus_Omega3[nrow, "rho"] = rho
corr_spearman_genus_Omega3[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_Omega3[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_Omega3[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_Omega3[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_Omega3$p.adjusted <- p.adjust(corr_spearman_genus_Omega3$p.value, method = "BH", n = 35)
corr_spearman_genus_Omega3$p.adjusted_PRE <- p.adjust(corr_spearman_genus_Omega3$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_Omega3$p.adjusted_POST <- p.adjust(corr_spearman_genus_Omega3$p.value_POST, method = "BH", n = 35)
corr_sig_genus_Omega3 <- filter(corr_spearman_genus_Omega3, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_Omega3, file = '/Users/student05/Documents/fa feces/tabellen/Omega3.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von Omega3 FA und genus-level
ggscatter(genus_FA, x='Omega3', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [nmol/g]', cor.coef.coord =c(0, -1.9), ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='Omega3', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [nmol/g]', cor.coef.coord =c(0, -1.9), ylab = 'log10 (Relative Abundance g__Oscillospira')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='Omega3', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Oscillospira',label = 'Proband')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium., x=Omega3)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance g__Eubacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega3', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Eubacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega3', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Collinsella')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega3', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance f__Coriobacteriaceae')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega3', y='k__Bacteria.p__Firmicutes.c__Bacilli.o__Lactobacillales.f__Streptococcaceae.g__Streptococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Streptococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega3', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega3', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Ruminococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega3', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop Omega6 FA und genus-level
corr_map_genus_Omega6 <- filter(genus_FA, !is.na(Omega6))
corr_spearman_genus_Omega6 <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_Omega6, !is.na(i))
y = tmp[,i]
x = tmp$Omega6
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Omega6
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Omega6
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_Omega6)+1
corr_spearman_genus_Omega6[nrow,"FA"] = "Omega6"
corr_spearman_genus_Omega6[nrow, "Genus"] = i
corr_spearman_genus_Omega6[nrow, "p.value"] = p
corr_spearman_genus_Omega6[nrow, "rho"] = rho
corr_spearman_genus_Omega6[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_Omega6[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_Omega6[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_Omega6[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_Omega6$p.adjusted <- p.adjust(corr_spearman_genus_Omega6$p.value, method = "BH", n = 35)
corr_spearman_genus_Omega6$p.adjusted_PRE <- p.adjust(corr_spearman_genus_Omega6$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_Omega6$p.adjusted_POST <- p.adjust(corr_spearman_genus_Omega6$p.value_POST, method = "BH", n = 35)
corr_sig_genus_Omega6 <- filter(corr_spearman_genus_Omega6, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_Omega6, file = '/Users/student05/Documents/fa feces/tabellen/Omega6.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
PLotten von Omega6 FA und genus-level
ggscatter(genus_FA, x='Omega6', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_FA, x='Omega6', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid excretion rate [%]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='Omega6', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Eubacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega6', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Collinsella')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega6', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance f__Coriobacteriaceae')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega6', y='k__Bacteria.p__Firmicutes.c__Bacilli.o__Lactobacillales.f__Streptococcaceae.g__Streptococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Streptococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega6', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega6', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega6', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Akkermansia')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Omega6', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Ruminococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop omega6/omega3-ratio und genus-level
corr_map_genus_ratio <- filter(genus_FA, !is.na(ratio))
corr_spearman_genus_ratio <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_ratio, !is.na(i))
y = tmp[,i]
x = tmp$ratio
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$ratio
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$ratio
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_ratio)+1
corr_spearman_genus_ratio[nrow,"FA"] = "ratio"
corr_spearman_genus_ratio[nrow, "Genus"] = i
corr_spearman_genus_ratio[nrow, "p.value"] = p
corr_spearman_genus_ratio[nrow, "rho"] = rho
corr_spearman_genus_ratio[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_ratio[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_ratio[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_ratio[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_ratio$p.adjusted <- p.adjust(corr_spearman_genus_ratio$p.value, method = "BH", n = 35)
corr_spearman_genus_ratio$p.adjusted_PRE <- p.adjust(corr_spearman_genus_ratio$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_ratio$p.adjusted_POST <- p.adjust(corr_spearman_genus_ratio$p.value_POST, method = "BH", n = 35)
corr_sig_genus_ratio <- filter(corr_spearman_genus_ratio, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_ratio, file = '/Users/student05/Documents/fa feces/tabellen/ratio.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
PLotten von omega6/omega3-ratio und genus-level
ggscatter(genus_FA, x='ratio', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggscatter(genus_FA, x='ratio', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Lachnospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Lachnospira')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='ratio', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Bacteroides')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggscatter(genus_FA, x='ratio', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Collinsella')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='ratio', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Ruminococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='ratio', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Phascolarctobacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='ratio', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop ungesaettigte FA und genus-level
corr_map_genus_unsat <- filter(genus_FA, !is.na(unsat))
corr_spearman_genus_unsat <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_unsat, !is.na(i))
y = tmp[,i]
x = tmp$unsat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$unsat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$unsat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_unsat)+1
corr_spearman_genus_unsat[nrow,"FA"] = "unsat"
corr_spearman_genus_unsat[nrow, "Genus"] = i
corr_spearman_genus_unsat[nrow, "p.value"] = p
corr_spearman_genus_unsat[nrow, "rho"] = rho
corr_spearman_genus_unsat[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_unsat[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_unsat[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_unsat[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_unsat$p.adjusted <- p.adjust(corr_spearman_genus_unsat$p.value, method = "BH", n = 35)
corr_spearman_genus_unsat$p.adjusted_PRE <- p.adjust(corr_spearman_genus_unsat$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_unsat$p.adjusted_POST <- p.adjust(corr_spearman_genus_unsat$p.value_POST, method = "BH", n = 35)
corr_sig_genus_unsat <- filter(corr_spearman_genus_unsat, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_genus_unsat, file = '/Users/student05/Documents/fa feces/tabellen/unsat.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
2.5 Omega-Fa Analysen, Aufnahem ueber Nahrung, Ausscheidung, Ausscheidungsrate , Absorptionsrate, EPA, DHA
Laden der Metadaten und testen auf Normalverteilung
FA_stool.o <- read.table("/Users/student05/Documents/Omega aufnahme 1.txt", sep = '\t', comment='',head=T)
View(FA_stool)
FA_stool.o <- subset(filter(FA_stool.o, !Proband == "33MP"))
FA_colnames.o <- colnames(FA_stool.o[, c(21:23)])
nd.FA.o <- data.frame()
for (i in FA_colnames.o) {
fit <- shapiro.test(as.matrix(as.data.frame(lapply(FA_stool.o[,i],
as.numeric))))
p = fit$p.value
nrow = nrow(nd.FA.o)+1
nd.FA.o[nrow, "column"] = i
nd.FA.o[nrow, "p.value"] = round(p, 4)
}
Plotten der Normalverteilungen
ggqqplot(FA_stool.o$Linolensaeure_f, ylab = "Fecal omega 3 FA concentration [g]", xlab = "SampleID")
ggqqplot(FA_stool.o$Linolsaeure_f, ylab = "Fecal omega 6 FA concentration [g]", xlab = "SampleID")
ggqqplot(FA_stool.o$Linolensaeure_i, ylab = "Intake omega 3 FA concentration [g]", xlab = "SampleID")
ggqqplot(FA_stool.o$EPA_i, ylab = "Intake EPA [g]", xlab = "SampleID")
ggqqplot(FA_stool.o$DHA_i, ylab = "Intake DHA [g]", xlab = "SampleID")
ggqqplot(FA_stool.o$AR_Linolensaeure, ylab = "precipitation rate omega 3 FA concentration [%]", xlab = "SampleID")
ggqqplot(FA_stool.o$AR_Linolsaeure, ylab = "precipitation rate omega 6 FA concentration [%]", xlab = "SampleID")
ggqqplot(FA_stool.o$A_Linolensaeure, ylab = "Intake in the body omega 3 FA [g]", xlab = "SampleID")
ggqqplot(FA_stool.o$A_Linolsaeure, ylab = "Intake in the body omega 6 FA [g]", xlab = "SampleID")
ggqqplot(FA_stool.o$AP_Linolensaeure, ylab = "percentage intake in the body omega 3 FA [g]", xlab = "SampleID")
ggqqplot(FA_stool.o$AP_Linolsaeure, ylab = "percentage intake in the body omega 6 FA [g]", xlab = "SampleID")
Filtern nach PRE und POST
FA_stool_pairs.o <- filter(FA_stool.o, Proband == "05AP" | Proband == "06WT"
| Proband == "07RW" | Proband == "13BS" | Proband == "17SK"
| Proband == "22WS" | Proband == "25FE" | Proband == "26FB"
| Proband == "28HM" | Proband == "29MK" | Proband == "30HB"
| Proband == "31KE" | Proband == "32FG" | Proband == "35AD"| Proband == "36ER"
| Proband == "37SD" | Proband == "38AR" | Proband == "40WA"
| Proband == "41ML" | Proband == "45GL" | Proband == "47OT"
| Proband == "50DM" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
FA_stool_pairs.o$Proband
FA_stool_pairs_PP.o <- filter(FA_stool_pairs.o, Time=="PRE" | Time=="POST")
Loop fuer Wilcoxon-test zwischen PRE und POST
wilcox_FA.o<- data_frame()
for (i in FA_colnames.o) {
tmp <- FA_stool_pairs_PP.o %>% drop_na(i)
x <- as.matrix(as.data.frame(lapply(tmp[,i], as.numeric)))
y <- FA_stool_pairs_PP.o$Time
tmp_wilcox <- pairwise.wilcox.test(x, y, p.adjust.method = 'BH', paired = T)
p <- tmp_wilcox$p.value
nrow = nrow(wilcox_FA.o)+1
wilcox_FA.o[nrow, "FA"] <- i
wilcox_FA.o[nrow, "Mean PRE"] <-round(mean(subset(filter(FA_stool_pairs.o,Time == "PRE")[,i],!is.na(i),na.rm = TRUE), 2, mean, na.rm = TRUE), 4)
wilcox_FA.o[nrow, "sd PRE"] <-round(sd(c(subset(filter(FA_stool_pairs.o,Time == "PRE")[,i],!is.na(i),na.rm = TRUE), na.rm = TRUE)), 4)
wilcox_FA.o[nrow, "Mean POST"] <-round(mean(subset(filter(FA_stool_pairs.o,Time == "POST")[,i],!is.na(i), na.rm = TRUE), 2, mean, na.rm = TRUE), 4)
wilcox_FA.o[nrow, "sd POST"] <- round(sd(c(subset(filter(FA_stool_pairs.o,Time == "POST")[,i],!is.na(i), na.rm = TRUE),na.rm = TRUE)), 4)
wilcox_FA.o[nrow, "p.value"] <- round(p, 4) }
Boxplot der Omega-FA je Zeitpunkt alle FA
FA_stool.melt.o <- melt(FA_stool_pairs.o, id.vars = 'Time', measure.vars = c('Linolensaeure_f', 'Linolsaeure_f', 'Linolensaeure_i', 'Linolsaeure_i'))
FA_stool.melt.o <- rename(FA_stool.melt.o, FA=variable)
FA_stool.melt.o <- rename(FA_stool.melt.o, Concentration=value)
FA_stool.melt.o$Time <- factor(FA_stool.melt.o$Time, levels = c("PRE", "POST"))
ggplot(FA_stool.melt.o,aes(x=Time, y=Concentration, fill= FA)) +
xlab ('Time Point') + ylab ('Concentration [g]') +
geom_boxplot() +
scale_fill_manual(labels = c("omega 3 fecal", "omega 6 fecal","omega 3 intake", "omega 6 intake"),
values = c("tomato", "yellowgreen", "steelblue2", "deeppink2")) +
theme(legend.position="top")+
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))
Omega 3 in mol
FA_stool.melt.o1 <- melt(FA_stool_pairs.o, id.vars = c('Time','Proband'), measure.vars = c('Linolensaeure_mol'))
FA_stool.melt.o1 <- rename(FA_stool.melt.o1, FA=variable)
FA_stool.melt.o1 <- rename(FA_stool.melt.o1, Concentration=value)
FA_stool.melt.o1$Time <- factor(FA_stool.melt.o1$Time, levels = c("PRE", "POST"))
ggplot(FA_stool.melt.o1,aes(x=Time, y=Concentration, fill= FA),label= 'Proband') +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("omega 3 fecal"),
values = c("tomato")) +
theme(legend.position="top")+
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
geom_text(aes(label=Proband),hjust=0, vjust=0)
pdf("/Users/student05/Documents/fertige Plots/Linolsäure.probands.pdf",width=7.5, height=10)
ggpaired(FA_stool.melt.o1, x='Time', y='Concentration', color = 'black', fill = 'Time', palette = c('skyblue','orchid4'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'FA', short.panel.labs = FALSE) +
xlab('Fäkale alpha-Linolensäurekonzentrationen [nmol/g]') + ylab('Konzentration [nmol/g]')+
theme(legend.position="top")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=0, hjust=1))
dev.off()
Omega 6 in mol
FA_stool.melt.o2 <- melt(FA_stool_pairs.o, id.vars = c('Time','Proband'), measure.vars = c('Linolsaeure_mol'))
FA_stool.melt.o2 <- rename(FA_stool.melt.o2, FA=variable)
FA_stool.melt.o2<- rename(FA_stool.melt.o2, Concentration=value)
FA_stool.melt.o2$Time <- factor(FA_stool.melt.o2$Time, levels = c("PRE", "POST"))
ggplot(FA_stool.melt.o2,aes(x=Time, y=Concentration, fill= FA),label= 'Proband') +
xlab ('Time Point') + ylab ('Concentration [nmol/g]') +
geom_boxplot() +
scale_fill_manual(labels = c("omega 6 fecal"),
values = c("yellowgreen")) +
theme(legend.position="top")+
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
geom_text(aes(label=Proband),hjust=0, vjust=0)
ggpaired(FA_stool.melt.o2, x='Time', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'FA', short.panel.labs = FALSE) +
xlab('fecal omega 6') + ylab('Concentration [nmol/g DW]') +
geom_text(aes(label=Proband),hjust=0, vjust=0)
Omega 3 Aufnahme PRE und POST
FA_stool.melt.o3 <- melt(FA_stool_pairs.o, id.vars = c('Time','Proband'), measure.vars = c('Linolensaeure_i'))
FA_stool.melt.o3 <- rename(FA_stool.melt.o3, FA=variable)
FA_stool.melt.o3 <- rename(FA_stool.melt.o3, Concentration=value)
FA_stool.melt.o3$Time <- factor(FA_stool.melt.o3$Time, levels = c("PRE", "POST"))
ggplot(FA_stool.melt.o3,aes(x=Time, y=Concentration, fill= FA)) +
xlab ('Time Point') + ylab ('Concentration [g]') +
geom_boxplot() +
scale_fill_manual(labels = c("omega 3 intake", "omega 6 intake"),
values = c("steelblue2")) +
theme(legend.position="top")+
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
geom_text(aes(label=Proband),hjust=0, vjust=0)
ggpaired(FA_stool.melt.o3, x='Time', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'FA', short.panel.labs = FALSE) +
xlab('intake omega 3') + ylab('Concentration [nmol/g DW]') +
geom_text(aes(label=Proband),hjust=0, vjust=0)
Omega 6 Aufnahme PRE und POST
FA_stool.melt.o4 <- melt(FA_stool_pairs.o, id.vars = c('Time','Proband'), measure.vars = c('Linolsaeure_i'))
FA_stool.melt.o4 <- rename(FA_stool.melt.o4, FA=variable)
FA_stool.melt.o4 <- rename(FA_stool.melt.o4, Concentration=value)
FA_stool.melt.o4$Time <- factor(FA_stool.melt.o4$Time, levels = c("PRE", "POST"))
ggplot(FA_stool.melt.o4,aes(x=Time, y=Concentration, fill= FA)) +
xlab ('Time Point') + ylab ('Concentration [g]') +
geom_boxplot() +
scale_fill_manual(labels = c("omega 6 intake"),
values = c("deeppink")) +
theme(legend.position="top")+
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
geom_text(aes(label=Proband),hjust=0, vjust=0)
ggpaired(FA_stool.melt.o4, x='Time', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'FA', short.panel.labs = FALSE) +
xlab('intake omega 6') + ylab('Concentration [nmol/g DW]') +
geom_text(aes(label=Proband),hjust=0, vjust=0)
3.3 Korrelationsanalysen Omega-FA und Taxa Metadaten hochladen, filtern und synchronisieren
relab_means <- read.table('/Users/student05/Documents/relative abundance/relab_means_per_timepoint.txt', sep ='\t', comment='', head=T)
relab_means_melt <- melt(relab_means, id=c('Proband', 'Time'))
relab_means_melt <- dplyr::rename(relab_means_melt, Taxa=variable)
relab_means_melt <- dplyr::rename(relab_means_melt, Relative_Abundance=value)
relab_phylum <- subset(relab_means_melt, !grepl("g__|f__|o__|c__", relab_means_melt$Taxa))
relab_phylum <- subset(relab_phylum, !grepl("k__Archaea", relab_phylum$Taxa))
relab_phylum$Time <- factor(relab_phylum$Time, levels=c('PRE','POST','FOLLOW-UP'))
relab_phylum_spread <- spread(relab_phylum, Taxa, Relative_Abundance, sep = NULL)
relab_genus <- subset(relab_means_melt, grepl("g__", relab_means_melt$Taxa))
relab_genus <- subset(relab_genus, !grepl("k__Archaea", relab_genus$Taxa))
relab_genus$Time <- factor(relab_genus$Time, levels = c('PRE','POST','FOLLOW-UP'))
relab_genus_spread <- spread(relab_genus, Taxa, Relative_Abundance, sep = NULL)
FA_stool.o <- read.table("/Users/student05/Documents/fa feces/FA fecal/omega/Omega aufnahme .txt", sep = '\t', comment='',head=T)
View(FA_stool)
FA_stool.o <- subset(filter(FA_stool.o, !Proband == "33MP"))
relab_phylum_ID <- relab_phylum_spread
relab_phylum_ID <- mutate(relab_phylum_ID, SampleID = paste(Proband, Time,sep="."))
row.names(relab_phylum_ID) <- relab_phylum_ID$SampleID
relab_genus_ID <- relab_genus_spread
relab_genus_ID <- mutate(relab_genus_ID, SampleID = paste(Proband, Time, sep ="."))
row.names(relab_genus_ID) <- relab_genus_ID$SampleID
FA_stool.o$Proband
FA_stool.o <- subset(filter(FA_stool.o, !Proband == "34WF",!Proband == "49RJ"))
FA_stool.o <- mutate(FA_stool.o, SampleID1 = paste(Proband, Time, sep = "."))
row.names(FA_stool.o) <- FA_stool.o$SampleID1
common.ids.relab <- intersect(rownames(FA_stool.o), rownames(relab_phylum_ID))
FA_stool.o <- FA_stool.o[common.ids.relab,]
relab_phylum_ID <- relab_phylum_ID[common.ids.relab,]
relab_genus_ID <- relab_genus_ID[common.ids.relab,]
Phylum-Level log transformation hinzufuegen von Pseudocount von 0.00001
relab_phylum_ID_log <- relab_phylum_ID[,c(3:8)] + 0.00001
relab_phylum_ID_log <- log10(relab_phylum_ID_log)
phylum_FA <- cbind(relab_phylum_ID_log, FA_stool.o[, c(2:23)])
Loop Korrelation faekale Linolensaeure und phylum-level
corr_map_phylum_omega6f <- filter(phylum_FA, !is.na(Linolsaeure_f))
corr_spearman_Phylum_omega6f <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_omega6f, !is.na(i))
y = tmp[,i]
x = tmp$Linolsaeure_f
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Linolsaeure_f
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Linolsaeure_f
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_omega6f)+1
corr_spearman_Phylum_omega6f[nrow,"FA"] <- "Linoleic fa"
corr_spearman_Phylum_omega6f[nrow, "Phylum"] = i
corr_spearman_Phylum_omega6f[nrow, "p.value"] = p
corr_spearman_Phylum_omega6f[nrow, "rho"] = rho
corr_spearman_Phylum_omega6f[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_omega6f[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_omega6f[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_omega6f[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_omega6f$p.adjusted <- p.adjust(corr_spearman_Phylum_omega6f$p.value, method = "BH", n = 35)
corr_spearman_Phylum_omega6f$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_omega6f$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_omega6f$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_omega6f$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_omega6f <- filter(corr_spearman_Phylum_omega6f, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
Plotten von faekaler Omega6 FA und Phylum-level Korrelationen
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=Linolsaeure_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggscatter(phylum_FA, x='Linolsaeure_f', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)',label = 'Proband')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_FA, x='Linolsaeure_f', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_FA, x='Linolensaeure_f', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord =c(0, -0.8), xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(phylum_FA, x='Linolensaeure_f', y='k__Bacteria.p__Bacteroidetes', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord =c(0, -0.8), xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(phylum_FA, x='Linolsaeure_f', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_FA, x='Linolensaeure_f', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Firmicutes, x=Linolsaeure_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=Linolsaeure_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=Linolsaeure_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=Linolsaeure_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)+
theme(legend.position="top")
Loop Linolensaeure und phylum-level
corr_map_phylum_omega3f <- filter(phylum_FA, !is.na(Linolsaeure_f))
corr_spearman_Phylum_omega3f <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_omega3f, !is.na(i))
y = tmp[,i]
x = tmp$Linolensaeure_f
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Linolensaeure_f
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Linolensaeure_f
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_omega6f)+1
corr_spearman_Phylum_omega3f[nrow,"FA"] <- "Linolenic fa"
corr_spearman_Phylum_omega3f[nrow, "Phylum"] = i
corr_spearman_Phylum_omega3f[nrow, "p.value"] = p
corr_spearman_Phylum_omega3f[nrow, "rho"] = rho
corr_spearman_Phylum_omega3f[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_omega3f[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_omega3f[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_omega3f[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_omega3f$p.adjusted <- p.adjust(corr_spearman_Phylum_omega3f$p.value, method = "BH", n = 35)
corr_spearman_Phylum_omega3f$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_omega3f$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_omega3f$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_omega3f$p.value_POST, method = "BH", n = 35)
Plotten von Korrelationen zwischen Omega3-FA und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=Linolensaeure_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggscatter(phylum_FA, x='Linolensaeure_f', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)',label='Proband')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Firmicutes, x=Linolensaeure_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=Linolensaeure_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
Loop Omega6 Aufnahme und phylum-level
corr_map_phylum_omega6i <- filter(phylum_FA, !is.na(Linolsaeure_i))
corr_spearman_Phylum_omega6i <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_omega6i, !is.na(i))
y = tmp[,i]
x = tmp$Linolsaeure_i
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Linolsaeure_i
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Linolsaeure_i
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_omega6i)+1
corr_spearman_Phylum_omega6i[nrow,"FA"] <- "Linoleic fa i"
corr_spearman_Phylum_omega6i[nrow, "Phylum"] = i
corr_spearman_Phylum_omega6i[nrow, "p.value"] = p
corr_spearman_Phylum_omega6i[nrow, "rho"] = rho
corr_spearman_Phylum_omega6i[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_omega6i[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_omega6i[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_omega6i[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_omega6i$p.adjusted <- p.adjust(corr_spearman_Phylum_omega6i$p.value, method = "BH", n = 35)
corr_spearman_Phylum_omega6i$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_omega6i$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_omega6i$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_omega6i$p.value_POST, method = "BH", n = 35)
Plotten von Korrelationen zwischen Omega6 Aufnahme und phylum-level
phylum_FA$Time <- factor(phylum_FA$Time, levels = c("PRE", "POST"))
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=Linolsaeure_i)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration intake [g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggscatter(phylum_FA, x='Linolsaeure_i', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration intake [g]', ylab = 'log10 (Relative Abundance p__Actinobacteria)', label = 'Proband')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=Linolsaeure_i)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration intake [g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Tenericutes, x=Linolsaeure_i)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Concentration intake [g]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
Loop Omega3 Aufnahme und phylum-level
corr_map_phylum_omega3i <- filter(phylum_FA, !is.na(Linolensaeure_i))
corr_spearman_Phylum_omega3i <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_omega3i, !is.na(i))
y = tmp[,i]
x = tmp$Linolensaeure_i
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Linolensaeure_i
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Linolensaeure_i
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_omega3i)+1
corr_spearman_Phylum_omega3i[nrow,"FA"] <- "Linolenic fa i"
corr_spearman_Phylum_omega3i[nrow, "Phylum"] = i
corr_spearman_Phylum_omega3i[nrow, "p.value"] = p
corr_spearman_Phylum_omega3i[nrow, "rho"] = rho
corr_spearman_Phylum_omega3i[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_omega3i[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_omega3i[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_omega3i[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_omega3i$p.adjusted <- p.adjust(corr_spearman_Phylum_omega3i$p.value, method = "BH", n = 35)
corr_spearman_Phylum_omega3i$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_omega3i$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_omega3i$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_omega3i$p.value_POST, method = "BH", n = 35)
Plotten Omega3 Aufnahme und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=Linolensaeure_i)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration intake [g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggscatter(phylum_FA, x='Linolensaeure_i', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration intake [g]', ylab = 'log10 (Relative Abundance p__Actinobacteria)',label = 'Proband')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=Linolensaeure_i)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration intake [g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Tenericutes, x=Linolensaeure_i)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration intake [g]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
Loop Omega3 FA Absorption in g
corr_map_phylum_omega3a <- filter(phylum_FA, !is.na(A_Linolensaeure))
corr_spearman_Phylum_omega3a <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_omega3a, !is.na(i))
y = tmp[,i]
x = tmp$A_Linolensaeure
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$A_Linolensaeure
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$A_Linolensaeure
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_omega3a)+1
corr_spearman_Phylum_omega3a[nrow,"FA"] <- "Linolenic fa body i"
corr_spearman_Phylum_omega3a[nrow, "Phylum"] = i
corr_spearman_Phylum_omega3a[nrow, "p.value"] = p
corr_spearman_Phylum_omega3a[nrow, "rho"] = rho
corr_spearman_Phylum_omega3a[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_omega3a[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_omega3a[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_omega3a[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_omega3a$p.adjusted <- p.adjust(corr_spearman_Phylum_omega3a$p.value, method = "BH", n = 35)
corr_spearman_Phylum_omega3a$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_omega3a$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_omega3a$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_omega3a$p.value_POST, method = "BH", n = 35)
Plotten von Omega3 Aufnahme in g und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=A_Linolensaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration intake [g]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=A_Linolensaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration intake [g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Tenericutes, x=A_Linolensaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration intake [g]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
Loop Omega3 Ausscheidungsrate in Prozent und phylum-level
corr_map_phylum_omega3ar <- filter(phylum_FA, !is.na(AR_Linolensaeure))
corr_spearman_Phylum_omega3ar <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_omega3ar, !is.na(i))
y = tmp[,i]
x = tmp$AR_Linolensaeure
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$AR_Linolensaeure
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$AR_Linolensaeure
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_omega3ar)+1
corr_spearman_Phylum_omega3ar[nrow,"FA"] <- "Linolenic fa Precipitation"
corr_spearman_Phylum_omega3ar[nrow, "Phylum"] = i
corr_spearman_Phylum_omega3ar[nrow, "p.value"] = p
corr_spearman_Phylum_omega3ar[nrow, "rho"] = rho
corr_spearman_Phylum_omega3ar[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_omega3ar[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_omega3ar[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_omega3ar[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_omega3ar$p.adjusted <- p.adjust(corr_spearman_Phylum_omega3ar$p.value, method = "BH", n = 35)
corr_spearman_Phylum_omega3ar$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_omega3ar$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_omega3ar$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_omega3ar$p.value_POST, method = "BH", n = 35)
Plotten Omega3 Ausscheidungsrate in Prozent und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=AR_Linolensaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=AR_Linolensaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Firmicutes, x=AR_Linolensaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggscatter(phylum_FA, x='AR_Linolensaeure', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid excretion rate [%]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=AR_Linolensaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=AR_Linolensaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggscatter(phylum_FA, x='AR_Linolensaeure', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid excretion rate [%]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_FA, x='AR_Linolensaeure', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid excretion rate [%]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop Omega6 Ausscheidungsrate in Prozent und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=AR_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=AR_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggscatter(phylum_FA, x='AR_Linolensaeure', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid excretion rate [%]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)',label= 'Proband')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Firmicutes, x=AR_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=AR_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=AR_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggscatter(phylum_FA, x='AR_Linolsaeure', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid excretion rate [%]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)',label = 'Proband')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Tenericutes, x=AR_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
Loop Omega6 Absorption in Prozent und phylum-level
corr_map_phylum_omega6ap <- filter(phylum_FA, !is.na(AP_Linolsaeure))
corr_spearman_Phylum_omega6ap <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_omega6ap, !is.na(i))
y = tmp[,i]
x = tmp$AP_Linolsaeure
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$AP_Linolsaeure
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$AP_Linolsaeure
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_omega6ap)+1
corr_spearman_Phylum_omega6ap[nrow,"FA"] <- "Linoleic fa i [%]"
corr_spearman_Phylum_omega6ap[nrow, "Phylum"] = i
corr_spearman_Phylum_omega6ap[nrow, "p.value"] = p
corr_spearman_Phylum_omega6ap[nrow, "rho"] = rho
corr_spearman_Phylum_omega6ap[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_omega6ap[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_omega6ap[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_omega6ap[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_omega6ap$p.adjusted <- p.adjust(corr_spearman_Phylum_omega6ap$p.value, method = "BH", n = 35)
corr_spearman_Phylum_omega6ap$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_omega6ap$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_omega6ap$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_omega6ap$p.value_POST, method = "BH", n = 35)
Plotten von Omega6 Absorption in Prozent und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=AP_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid intake rate [%]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=AP_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid intake rate [%]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Firmicutes, x=AP_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=AP_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid intake rate [%]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=AP_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid intake rate [%]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Tenericutes, x=AR_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
Loop Omega3 Absorption in Prozent und phylum-level
corr_map_phylum_omega3ap <- filter(phylum_FA, !is.na(AP_Linolensaeure))
corr_spearman_Phylum_omega3ap <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_omega3ap, !is.na(i))
y = tmp[,i]
x = tmp$AP_Linolensaeure
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$AP_Linolensaeure
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$AP_Linolensaeure
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_omega3ap)+1
corr_spearman_Phylum_omega3ap[nrow,"FA"] <- "Linolenic fa i [%]"
corr_spearman_Phylum_omega3ap[nrow, "Phylum"] = i
corr_spearman_Phylum_omega3ap[nrow, "p.value"] = p
corr_spearman_Phylum_omega3ap[nrow, "rho"] = rho
corr_spearman_Phylum_omega3ap[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_omega3ap[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_omega3ap[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_omega3ap[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_omega3ap$p.adjusted <- p.adjust(corr_spearman_Phylum_omega3ap$p.value, method = "BH", n = 35)
corr_spearman_Phylum_omega3ap$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_omega3ap$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_omega3ap$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_omega3ap$p.value_POST, method = "BH", n = 35)
Plotten von Omega3 Absorption in Prozent und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=AP_Linolensaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid intake rate [%]') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=AP_Linolensaeure)) + geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid intake rate [%]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Firmicutes, x=AP_Linolensaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=AP_Linolensaeure)) + geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid intake rate [%]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Bacteroidetes, x=AP_Linolensaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid intake rate [%]') +
ylab('log10 (Relative Abundance p__Bacteroidetes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Tenericutes, x=AR_Linolsaeure)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linoleic fatty acid Precipitation rate [%]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
Loop EPA und phylum-level
corr_map_phylum_epa <- filter(phylum_FA, !is.na(EPA_i))
corr_spearman_Phylum_epa <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_epa, !is.na(i))
y = tmp[,i]
x = tmp$EPA_i
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$EPA_i
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$EPA_i
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_epa)+1
corr_spearman_Phylum_epa[nrow,"FA"] <- "EPA intake [g]"
corr_spearman_Phylum_epa[nrow, "Phylum"] = i
corr_spearman_Phylum_epa[nrow, "p.value"] = p
corr_spearman_Phylum_epa[nrow, "rho"] = rho
corr_spearman_Phylum_epa[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_epa[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_epa[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_epa[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_epa$p.adjusted <- p.adjust(corr_spearman_Phylum_epa$p.value, method = "BH", n = 35)
corr_spearman_Phylum_epa$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_epa$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_epa$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_epa$p.value_POST, method = "BH", n = 35)
Plotten von EPA und phylum-level
ggscatter(phylum_FA, x='EPA_i', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'EPA fatty acid intake [g]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)',label= 'Proband')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=EPA_i)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('EPA intake [g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Verrucomicrobia, x=EPA_i)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('EPA intake [g]') +
ylab('log10 (Relative Abundance p__Verrucomicrobia)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Tenericutes, x=EPA_i)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('EPA intake [g]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
Loop DHA und phylum-level
corr_map_phylum_dha <- filter(phylum_FA, !is.na(DHA_i))
corr_spearman_Phylum_dha <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_dha, !is.na(i))
y = tmp[,i]
x = tmp$DHA_i
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$DHA_i
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$DHA_i
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_dha)+1
corr_spearman_Phylum_dha[nrow,"FA"] <- "DHA intake [g]"
corr_spearman_Phylum_dha[nrow, "Phylum"] = i
corr_spearman_Phylum_dha[nrow, "p.value"] = p
corr_spearman_Phylum_dha[nrow, "rho"] = rho
corr_spearman_Phylum_dha[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_dha[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_dha[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_dha[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_dha$p.adjusted <- p.adjust(corr_spearman_Phylum_dha$p.value, method = "BH", n = 35)
corr_spearman_Phylum_dha$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_dha$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_dha$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_dha$p.value_POST, method = "BH", n = 35)
Plotten von DHA und phylum-level Korrelationen
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=DHA_i)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('DHA intake [g]') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Tenericutes, x=DHA_i)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('DHA intake [g]') +
ylab('log10 (Relative Abundance p__Tenericutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggscatter(phylum_FA, x='DHA_i', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'DHA fatty acid intake [g]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)',label= 'Proband')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop faekales Omega6/Omega3-ratio und phylum-level
corr_map_phylum_ra <- filter(phylum_FA, !is.na(ratio_f))
corr_spearman_Phylum_ra <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_ra, !is.na(i))
y = tmp[,i]
x = tmp$ratio_f
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$ratio_f
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$ratio_f
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_ra)+1
corr_spearman_Phylum_ra[nrow,"FA"] <- "ratio omega6/omega3 fecal"
corr_spearman_Phylum_ra[nrow, "Phylum"] = i
corr_spearman_Phylum_ra[nrow, "p.value"] = p
corr_spearman_Phylum_ra[nrow, "rho"] = rho
corr_spearman_Phylum_ra[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_ra[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_ra[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_ra[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_ra$p.adjusted <- p.adjust(corr_spearman_Phylum_ra$p.value, method = "BH", n = 35)
corr_spearman_Phylum_ra$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_ra$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_ra$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_ra$p.value_POST, method = "BH", n = 35)
Plotten von faekalem Omega6/Omega3-ratio und phylum-level
ggplot(phylum_FA, aes(y=k__Bacteria.p__Actinobacteria, x=ratio_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('omega 6/omega 3 ratio fecal') +
ylab('log10 (Relative Abundance p__Actinobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Proteobacteria, x=ratio_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('omega 6/omega 3 ratio fecal') +
ylab('log10 (Relative Abundance p__Proteobacteria)')+
facet_wrap(~Time)+
theme(legend.position="top")
ggplot(phylum_FA, aes(y=k__Bacteria.p__Firmicutes, x=ratio_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('omega 6/omega 3 ratio fecal') +
ylab('log10 (Relative Abundance p__Firmicutes)')+
facet_wrap(~Time)+
theme(legend.position="top")
Genus-level, Filtern der Metadaten, log transformation und hinzufuegen von Pseudocount 0.00001
genus_colnames <- colnames(relab_genus_spread[, c(3:31)])
relab_genus_ID_log <- relab_genus_ID[,c(3:31)] + 0.00001
relab_genus_ID_log <- log10(relab_genus_ID_log)
genus_FA <- cbind(relab_genus_ID_log, FA_stool.o)
genus_FA$Time <- factor(genus_FA$Time, levels = c("PRE", "POST"))
Loop faekale Omega3 FA und genus-level
corr_map_genus_omega3f <- filter(genus_FA, !is.na(Linolensaeure_f))
corr_spearman_genus_omega3f <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_omega3f, !is.na(i))
y = tmp[,i]
x = tmp$Linolensaeure_f
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Linolensaeure_f
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Linolensaeure_f
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_omega3f)+1
corr_spearman_genus_omega3f[nrow,"FA"] = "Linolenic fa fecal"
corr_spearman_genus_omega3f[nrow, "Genus"] = i
corr_spearman_genus_omega3f[nrow, "p.value"] = p
corr_spearman_genus_omega3f[nrow, "rho"] = rho
corr_spearman_genus_omega3f[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_omega3f[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_omega3f[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_omega3f[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_omega3f$p.adjusted <- p.adjust(corr_spearman_genus_omega3f$p.value, method = "BH", n = 35)
corr_spearman_genus_omega3f$p.adjusted_PRE <- p.adjust(corr_spearman_genus_omega3f$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_omega3f$p.adjusted_POST <- p.adjust(corr_spearman_genus_omega3f$p.value_POST, method = "BH", n = 35)
Plotten faekale Omega3 FA und genus-level
ggscatter(genus_FA, x='Linolensaeure_mol', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [nmol/g]', cor.coef.coord =c(0, -1.9), ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='Linolensaeure_mol', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [nmol/g]', cor.coef.coord =c(0, -1.9), ylab = 'log10 (Relative Abundance g__Oscillospira')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='Linolsaeure_f', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Oscillospira',label = 'Proband')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggplot(genus_FA, aes(y=k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium., x=Linolensaeure_f)) +
geom_point(aes(color=Time)) + scale_color_manual(values = c('yellowgreen', 'coral2', 'steelblue2')) +
geom_smooth(method = 'lm', color='grey65') + xlab('Linolenic fatty acid Concentration fecal [g]') +
ylab('log10 (Relative Abundance g__Eubacterium)')+
facet_wrap(~Time)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolensaeure_f', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Eubacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolensaeure_f', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Collinsella')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolensaeure_f', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance f__Coriobacteriaceae')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolensaeure_f', y='k__Bacteria.p__Firmicutes.c__Bacilli.o__Lactobacillales.f__Streptococcaceae.g__Streptococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Streptococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolensaeure_f', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolensaeure_f', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Ruminococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolensaeure_f', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop faekale Omega6-FA und genus-level
corr_map_genus_omega6f <- filter(genus_FA, !is.na(Linolsaeure_f))
corr_spearman_genus_omega6f <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_omega6f, !is.na(i))
y = tmp[,i]
x = tmp$Linolsaeure_f
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Linolensaeure_f
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Linolsaeure_f
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_omega6f)+1
corr_spearman_genus_omega6f[nrow,"FA"] = "Linoleic fa fecal"
corr_spearman_genus_omega6f[nrow, "Genus"] = i
corr_spearman_genus_omega6f[nrow, "p.value"] = p
corr_spearman_genus_omega6f[nrow, "rho"] = rho
corr_spearman_genus_omega6f[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_omega6f[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_omega6f[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_omega6f[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_omega6f$p.adjusted <- p.adjust(corr_spearman_genus_omega6f$p.value, method = "BH", n = 35)
corr_spearman_genus_omega6f$p.adjusted_PRE <- p.adjust(corr_spearman_genus_omega6f$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_omega6f$p.adjusted_POST <- p.adjust(corr_spearman_genus_omega6f$p.value_POST, method = "BH", n = 35)
Plotten faekale Omega6-FA und genus-level
ggscatter(genus_FA, x='Linolsaeure_f', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='Linolsaeure_f', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Eubacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolsaeure_f', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Collinsella')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolsaeure_f', y='k__Bacteria.p__Firmicutes.c__Bacilli.o__Lactobacillales.f__Streptococcaceae.g__Streptococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Streptococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolsaeure_f', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolsaeure_f', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolsaeure_f', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Akkermansia')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='Linolsaeure_f', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Concentration fecal [g]', ylab = 'log10 (Relative Abundance g__Ruminococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop prozentuale Ausscheidungsrate Omega3-FA und genus-level
corr_map_genus_omega3ar <- filter(genus_FA, !is.na(AR_Linolensaeure))
corr_spearman_genus_omega3ar <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_omega3ar, !is.na(i))
y = tmp[,i]
x = tmp$AR_Linolensaeure
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$AR_Linolensaeure
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$AR_Linolensaeure
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_omega3ar)+1
corr_spearman_genus_omega3ar[nrow,"FA"] = "Linolenic fa Precipitation rate "
corr_spearman_genus_omega3ar[nrow, "Genus"] = i
corr_spearman_genus_omega3ar[nrow, "p.value"] = p
corr_spearman_genus_omega3ar[nrow, "rho"] = rho
corr_spearman_genus_omega3ar[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_omega3ar[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_omega3ar[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_omega3ar[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_omega3ar$p.adjusted <- p.adjust(corr_spearman_genus_omega3ar$p.value, method = "BH", n = 35)
corr_spearman_genus_omega3ar$p.adjusted_PRE <- p.adjust(corr_spearman_genus_omega3ar$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_omega3ar$p.adjusted_POST <- p.adjust(corr_spearman_genus_omega3ar$p.value_POST, method = "BH", n = 35)
Plotten prozentuale Ausscheidungsrate Omega3-FA und genus-level
ggscatter(genus_FA, x='AR_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='AR_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Blautia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Blautia')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Eubacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Bacilli.o__Lactobacillales.f__Streptococcaceae.g__Streptococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Streptococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop prozentuale Ausscheidungsrate Omega6-FA und genus-level
corr_map_genus_omega6ar <- filter(genus_FA, !is.na(AR_Linolsaeure))
corr_spearman_genus_omega6ar <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_omega6ar, !is.na(i))
y = tmp[,i]
x = tmp$AR_Linolsaeure
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$AR_Linolsaeure
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$AR_Linolsaeure
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_omega6ar)+1
corr_spearman_genus_omega6ar[nrow,"FA"] = "Linoleic fa Precipitation rate "
corr_spearman_genus_omega6ar[nrow, "Genus"] = i
corr_spearman_genus_omega6ar[nrow, "p.value"] = p
corr_spearman_genus_omega6ar[nrow, "rho"] = rho
corr_spearman_genus_omega6ar[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_omega6ar[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_omega6ar[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_omega6ar[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_omega6ar$p.adjusted <- p.adjust(corr_spearman_genus_omega6ar$p.value, method = "BH", n = 35)
corr_spearman_genus_omega6ar$p.adjusted_PRE <- p.adjust(corr_spearman_genus_omega6ar$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_omega6ar$p.adjusted_POST <- p.adjust(corr_spearman_genus_omega6ar$p.value_POST, method = "BH", n = 35)
Plotten prozentuale Omega6 Ausscheidungsrate und genus-level
ggscatter(genus_FA, x='AR_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolsaeure', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Prevotella')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolsaeure', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Bacteroides')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Blautia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Blautia')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Eubacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Bacilli.o__Lactobacillales.f__Streptococcaceae.g__Streptococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Streptococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolsaeure', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance f__Rikenellaceae')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AR_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop absorbierte Omega3-FA in g und genus-level
corr_map_genus_omega3a <- filter(genus_FA, !is.na(A_Linolensaeure))
corr_spearman_genus_omega3a <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_omega3a, !is.na(i))
y = tmp[,i]
x = tmp$A_Linolensaeure
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$A_Linolensaeure
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$A_Linolensaeure
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_omega3a)+1
corr_spearman_genus_omega3a[nrow,"FA"] = "Linolenic fa intake into the body "
corr_spearman_genus_omega3a[nrow, "Genus"] = i
corr_spearman_genus_omega3a[nrow, "p.value"] = p
corr_spearman_genus_omega3a[nrow, "rho"] = rho
corr_spearman_genus_omega3a[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_omega3a[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_omega3a[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_omega3a[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_omega3a$p.adjusted <- p.adjust(corr_spearman_genus_omega3a$p.value, method = "BH", n = 35)
corr_spearman_genus_omega3a$p.adjusted_PRE <- p.adjust(corr_spearman_genus_omega3a$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_omega3a$p.adjusted_POST <- p.adjust(corr_spearman_genus_omega3a$p.value_POST, method = "BH", n = 35)
Plotten absorbierte Omega3-FA in g und genus-level
ggscatter(genus_FA, x='A_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid Precipitation rate [%]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='A_Linolensaeure', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid absorbed into the body [g]', ylab = 'log10 (Relative Abundance g__Prevotella')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='A_Linolensaeure', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid absorbed into the body [g]', ylab = 'log10 (Relative Abundance g__Bacteroides')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='A_Linolensaeure', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__.Barnesiellaceae..g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid absorbed into the body [g]', ylab = 'log10 (Relative Abundance f__Barnesiellaceae')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='A_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Lachnospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid absorbed into the body [g]', ylab = 'log10 (Relative Abundance g__Lachnospira')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='A_Linolensaeure', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid absorbed into the body [g]', ylab = 'log10 (Relative Abundance g__Collinsella')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop absorbierte Omega6-FA in g und genus-level
corr_map_genus_omega6a <- filter(genus_FA, !is.na(A_Linolsaeure))
corr_spearman_genus_omega6a <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_omega6a, !is.na(i))
y = tmp[,i]
x = tmp$A_Linolsaeure
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$A_Linolsaeure
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$A_Linolsaeure
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_omega6a)+1
corr_spearman_genus_omega6a[nrow,"FA"] = "Linoleic fa intake into the body "
corr_spearman_genus_omega6a[nrow, "Genus"] = i
corr_spearman_genus_omega6a[nrow, "p.value"] = p
corr_spearman_genus_omega6a[nrow, "rho"] = rho
corr_spearman_genus_omega6a[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_omega6a[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_omega6a[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_omega6a[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_omega6a$p.adjusted <- p.adjust(corr_spearman_genus_omega6a$p.value, method = "BH", n = 35)
corr_spearman_genus_omega6a$p.adjusted_PRE <- p.adjust(corr_spearman_genus_omega6a$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_omega6a$p.adjusted_POST <- p.adjust(corr_spearman_genus_omega6a$p.value_POST, method = "BH", n = 35)
Plotten absorbierte Omega6-FA in g und genus-level
ggscatter(genus_FA, x='A_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absiorbed into the body [g]', ylab = 'log10 (Relative Abundance g__Phascolarctobacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='A_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absiorbed into the body [g]', ylab = 'log10 (Relative Abundance g__Ruminococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='A_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absiorbed into the body [g]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='A_Linolsaeure', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absorbed into the body [g]', ylab = 'log10 (Relative Abundance g__Prevotella')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='A_Linolsaeure', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absorbed into the body [g]', ylab = 'log10 (Relative Abundance g__Bacteroides')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_FA, x='A_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absorbed into the body [g]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop prozentuale Omega3-FA Absorption und genus-level
corr_map_genus_omega3ap <- filter(genus_FA, !is.na(AP_Linolensaeure))
corr_spearman_genus_omega3ap <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_omega3ap, !is.na(i))
y = tmp[,i]
x = tmp$AP_Linolensaeure
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$AP_Linolensaeure
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$AP_Linolensaeure
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_omega3ap)+1
corr_spearman_genus_omega3ap[nrow,"FA"] = "Linolenic fa intake into the body [%] "
corr_spearman_genus_omega3ap[nrow, "Genus"] = i
corr_spearman_genus_omega3ap[nrow, "p.value"] = p
corr_spearman_genus_omega3ap[nrow, "rho"] = rho
corr_spearman_genus_omega3ap[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_omega3ap[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_omega3ap[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_omega3ap[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_omega3ap$p.adjusted <- p.adjust(corr_spearman_genus_omega3ap$p.value, method = "BH", n = 35)
corr_spearman_genus_omega3ap$p.adjusted_PRE <- p.adjust(corr_spearman_genus_omega3ap$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_omega3ap$p.adjusted_POST <- p.adjust(corr_spearman_genus_omega3ap$p.value_POST, method = "BH", n = 35)
Plotten prozentuale Omega3-FA Absorption und genus-level
ggscatter(genus_FA, x='AP_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AP_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance g__Eubacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AP_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance f__Lachnospiraceae')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AP_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Bacilli.o__Lactobacillales.f__Streptococcaceae.g__Streptococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance g__Streptococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AP_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AP_Linolensaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linolenic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop prozentuale Omega6-FA Absorption und genus-level
corr_map_genus_omega6ap <- filter(genus_FA, !is.na(AP_Linolsaeure))
corr_spearman_genus_omega6ap <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_omega6ap, !is.na(i))
y = tmp[,i]
x = tmp$AP_Linolsaeure
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$AP_Linolsaeure
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$AP_Linolsaeure
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_omega6ap)+1
corr_spearman_genus_omega6ap[nrow,"FA"] = "Linoleic fa intake into the body [%] "
corr_spearman_genus_omega6ap[nrow, "Genus"] = i
corr_spearman_genus_omega6ap[nrow, "p.value"] = p
corr_spearman_genus_omega6ap[nrow, "rho"] = rho
corr_spearman_genus_omega6ap[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_omega6ap[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_omega6ap[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_omega6ap[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_omega6ap$p.adjusted <- p.adjust(corr_spearman_genus_omega6ap$p.value, method = "BH", n = 35)
corr_spearman_genus_omega6ap$p.adjusted_PRE <- p.adjust(corr_spearman_genus_omega6ap$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_omega3ap$p.adjusted_POST <- p.adjust(corr_spearman_genus_omega3ap$p.value_POST, method = "BH", n = 35)
Plotten prozentuale Omega6-FA Absorption und genus-level
ggscatter(genus_FA, x='AP_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AP_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance g__Eubacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AP_Linolsaeure', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance g__Bacteroides')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AP_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Bacilli.o__Lactobacillales.f__Streptococcaceae.g__Streptococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance g__Streptococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AP_Linolsaeure', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance g__Akkermansia')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AP_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='AP_Linolsaeure', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Linoleic fatty acid absorbed into the body [%]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop EPA-Aufnahme und genus-level
corr_map_genus_omegaepa <- filter(genus_FA, !is.na(EPA_i))
corr_spearman_genus_omegaepa <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_omegaepa, !is.na(i))
y = tmp[,i]
x = tmp$EPA_i
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$EPA_i
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$EPA_i
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_omegaepa)+1
corr_spearman_genus_omegaepa[nrow,"FA"] = "EPA intake [g] "
corr_spearman_genus_omegaepa[nrow, "Genus"] = i
corr_spearman_genus_omegaepa[nrow, "p.value"] = p
corr_spearman_genus_omegaepa[nrow, "rho"] = rho
corr_spearman_genus_omegaepa[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_omegaepa[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_omegaepa[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_omegaepa[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_omegaepa$p.adjusted <- p.adjust(corr_spearman_genus_omegaepa$p.value, method = "BH", n = 35)
corr_spearman_genus_omegaepa$p.adjusted_PRE <- p.adjust(corr_spearman_genus_omegaepa$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_omegaepa$p.adjusted_POST <- p.adjust(corr_spearman_genus_omegaepa$p.value_POST, method = "BH", n = 35)
Plotten von EPA-Aufnahme und genus-level
ggscatter(genus_FA, x='EPA_i', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'EPA fatty acid intake [g]', ylab = 'log10 (Relative Abundance g__Eubacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='EPA_i', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'EPA fatty acid intake [g]', ylab = 'log10 (Relative Abundance g__Bacteroides')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='EPA_i', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'EPA fatty acid intake [g]', ylab = 'log10 (Relative Abundance g__Akkermansia')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='EPA_i', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'EPA fatty acid intake [g]', ylab = 'log10 (Relative Abundance g__Ruminococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='EPA_i', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'EPA fatty acid intake [g]', ylab = 'log10 (Relative Abundance g__Phascolarctobacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='EPA_i', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'EPA fatty acid intake [g]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop DHA-Aufnahme und genus-level
corr_map_genus_omegadha <- filter(genus_FA, !is.na(DHA_i))
corr_spearman_genus_omegadha <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_omegadha, !is.na(i))
y = tmp[,i]
x = tmp$DHA_i
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$DHA_i
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$DHA_i
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_omegadha)+1
corr_spearman_genus_omegadha[nrow,"FA"] = "DHA intake [g] "
corr_spearman_genus_omegadha[nrow, "Genus"] = i
corr_spearman_genus_omegadha[nrow, "p.value"] = p
corr_spearman_genus_omegadha[nrow, "rho"] = rho
corr_spearman_genus_omegadha[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_omegadha[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_omegadha[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_omegadha[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_omegadha$p.adjusted <- p.adjust(corr_spearman_genus_omegadha$p.value, method = "BH", n = 35)
corr_spearman_genus_omegadha$p.adjusted_PRE <- p.adjust(corr_spearman_genus_omegadha$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_omegadha$p.adjusted_POST <- p.adjust(corr_spearman_genus_omegadha$p.value_POST, method = "BH", n = 35)
Plotten DHA-Aufnahme und genus-level
ggscatter(genus_FA, x='DHA_i', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'DHA fatty acid intake [g]', ylab = 'log10 (Relative Abundance g__Eubacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='DHA_i', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Blautia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'DHA fatty acid intake [g]', ylab = 'log10 (Relative Abundance g__Blautia')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='DHA_i', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'DHA fatty acid intake [g]', ylab = 'log10 (Relative Abundance g__Bacteroides')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='DHA_i', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'DHA fatty acid intake [g]', ylab = 'log10 (Relative Abundance g__Ruminococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='DHA_i', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'DHA fatty acid intake [g]', ylab = 'log10 (Relative Abundance g__Phascolarctobacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='DHA_i', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'DHA fatty acid intake [g]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Loop fäkales Omega6/Omega3-ratio und genus-level
corr_map_genus_ra <- filter(genus_FA, !is.na(ratio_f))
corr_spearman_genus_ra <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_ra, !is.na(i))
y = tmp[,i]
x = tmp$ratio_f
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$ratio_f
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$ratio_f
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_ra)+1
corr_spearman_genus_ra[nrow,"FA"] = "omega6/omega3 ratio "
corr_spearman_genus_ra[nrow, "Genus"] = i
corr_spearman_genus_ra[nrow, "p.value"] = p
corr_spearman_genus_ra[nrow, "rho"] = rho
corr_spearman_genus_ra[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_ra[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_ra[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_ra[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_ra$p.adjusted <- p.adjust(corr_spearman_genus_ra$p.value, method = "BH", n = 35)
corr_spearman_genus_ra$p.adjusted_PRE <- p.adjust(corr_spearman_genus_ra$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_ra$p.adjusted_POST <- p.adjust(corr_spearman_genus_ra$p.value_POST, method = "BH", n = 35)
Plotten Omega6/Omega3-ratio und genus-level
ggscatter(genus_FA, x='ratio_f', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggscatter(genus_FA, x='ratio_f', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Lachnospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Lachnospira')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='ratio_f', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Bacteroides')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggscatter(genus_FA, x='ratio_f', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Collinsella')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='ratio_f', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Ruminococcus')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='ratio_f', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Phascolarctobacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggscatter(genus_FA, x='ratio_f', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'omega 6/omega 3 ratio fecal', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black", angle = 90))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
- Sättigungstypen Einteilung der Sättigungstypen nach fäkaler Fettsäuresättigung: sat, unsat, change.sat, change.unsat Laden der Metadaten Vergleich der Aufnahme von Fettsäuren über Nahrung zwischen den Sättigungstypen
FA_stool.ST <- read.table("/Users/student05/Documents/fa saturation mit intake types.txt", sep = '\t', comment='',
head=T)
View(FA_stool.ST)
FA_stool.ST$Time <-factor(FA_stool.ST$Time, levels = c("PRE", "POST"))
row.names(FA_stool.ST) <- FA_stool.ST$SampleID
FA_stool.ST$Proband
FA_stool.ST <- subset(filter(FA_stool.ST, !SampleID == "ST.35AD.0U1"))
FA_stool.ST <- subset(filter(FA_stool.ST, !Proband == "33MP", !Proband == "35AD", !Proband == "34WF", !Proband == "49RJ"))
comparison_sat <- list(c("sat", "unsat"))
comparison_change <- list(c("change.sat", "change.unsat"))
comparison_time <- list(c("PRE", "POST"))
Korrelationen durch die Nahrung aufgenommene ungesättigte FA mit fäkalen ungesättigten FA
stool.melt.unsat <- melt(FA_stool.ST, id.vars = c('Time','Proband'), measure.vars = c('unsat', 'unsat.i'))
stool.melt.unsat<- dplyr::rename(stool.melt.unsat, FA=variable)
stool.melt.unsat<- dplyr::rename(stool.melt.unsat, Concentration=value)
stool.melt.unsat$Time <- factor(stool.melt.unsat$Time, levels = c("PRE", "POST"))
ggpaired(stool.melt.unsat, x='FA', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, facet.by = 'Time', short.panel.labs = FALSE) +
xlab('unsaturated fatty acids fecal and intake') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ Time, scales="free")+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='unsat', y='unsat.i',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations fecal [nmol/g]', ylab = 'Unsaturated fatty acids concentrations intake [g]')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='unsat', y='unsat.i', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations fecal [nmol/g]', ylab = 'Unsaturated fatty acids concentrations intake [g]')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Korrelationen durch die Nahrung aufgenommene gesättigte FA mit fäkalen gesättigten FA
stool.melt.sat <- melt(FA_stool.ST, id.vars = c('Time','Proband'), measure.vars = c('sat', 'sat.i'))
stool.melt.sat<- dplyr::rename(stool.melt.sat, FA=variable)
stool.melt.sat<- dplyr::rename(stool.melt.sat, Concentration=value)
stool.melt.sat$Time <- factor(stool.melt.sat$Time, levels = c("PRE", "POST"))
ggpaired(stool.melt.sat, x='FA', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, facet.by = 'Time', short.panel.labs = FALSE) +
xlab('saturated fatty acids fecal and intake') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ Time, scales="free")+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='sat', y='sat.i',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations fecal [nmol/g]', ylab = 'Saturated fatty acids concentrations intake [g]')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='sat', y='sat.i', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations fecal [nmol/g]', ylab = 'Saturated fatty acids concentrations intake [g]')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Wilcoxon-Test zwischen Sättigungstypen und Fettsäureaufnahme durch Nahrung
pairwise.wilcox.test(subset(filter(FA_stool.ST, Time == "PRE"))$sat.i, subset(filter(FA_stool.ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Time == "POST"))$sat.i, subset(filter(FA_stool.ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Time == "PRE"))$unsat.i, subset(filter(FA_stool.ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Time == "POST"))$unsat.i, subset(filter(FA_stool.ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "sat"))$sat.i, subset(filter(FA_stool.ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired =F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "unsat"))$sat.i, subset(filter(FA_stool.ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired= F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "change.sat"))$sat.i, subset(filter(FA_stool.ST, Phenotype == "change.sat"))$Time, p.adjust.method = 'BH', paired =T)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "change.unsat"))$sat.i, subset(filter(FA_stool.ST, Phenotype == "change.unsat"))$Time, p.adjust.method = 'BH', paired= F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "sat"))$unsat.i, subset(filter(FA_stool.ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired =F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "unsat"))$unsat.i, subset(filter(FA_stool.ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired= F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "change.sat"))$unsat.i, subset(filter(FA_stool.ST, Phenotype == "change.sat"))$Time, p.adjust.method = 'BH', paired =T)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "change.unsat"))$unsat.i, subset(filter(FA_stool.ST, Phenotype == "change.unsat"))$Time, p.adjust.method = 'BH', paired= F)
Plotten der Unterschiede zwischen den Sättigungstypen
FA_stool.ST$Time <- factor(FA_stool.ST$Time, levels = c("PRE", "POST"))
ggplot(subset(filter(FA_stool.ST)), aes(x=Phenotype, y=sat.i)) + xlab('Phenotype') + ylab('Intake Saturated fatty acid Concentration [g]') +
geom_boxplot(fill='whitesmoke', color='black') +
geom_dotplot(binaxis= 'y', stackdir = 'center', dotsize = 0.3, fill = 'grey22', color='grey22') +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat) + facet_wrap(~Time)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(subset(filter(FA_stool.ST)), aes(x=Phenotype, y=unsat.i)) + xlab('Phenotype') + ylab('Intake unsaturated fatty acid Concentration [g]') +
geom_boxplot(fill='whitesmoke', color='black') +
geom_dotplot(binaxis= 'y', stackdir = 'center', dotsize = 0.3, fill = 'grey22', color='grey22') +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat) + facet_wrap(~Time)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(subset(filter(FA_stool.ST)), aes(x=Time, y=sat.i)) + xlab('Time Point') +
ylab('Intake saturated fatty acid Concentration [g]') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color= 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = F, aes(label= ..p.signif..), comparisons = comparison_time)
ggplot(subset(filter(FA_stool.ST)), aes(x=Time, y=unsat.i)) + xlab('Time Point') +
ylab('Intake unaturated fatty acid Concentration [g]') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color= 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = F, aes(label= ..p.signif..), comparisons = comparison_time)
Bestimmen der HDL und LDL Konzentrationen und Ratio der Sättigungstypen
Plotten von Korrelation zwischen LDL und fäkalen gesättigten FA
ggscatter(FA_stool.ST, x='sat', y='LDL',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations fecal [nmol/g]', ylab = 'LDL Concentration [mg/dl]')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='sat', y='LDL', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations fecal [nmol/g]', ylab = 'LDL Concentration [mg/dl]')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Plotten von Korrelationen zwischen HDL und fäkalen gesättigten FA
ggscatter(FA_stool.ST, x='sat', y='HDL',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations fecal [nmol/g]', ylab = 'HDL Concentration [mg/dl]')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='sat', y='HDL', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations fecal [nmol/g]', ylab = 'HDL Concentration [mg/dl]')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Plotten von Korrelationen zwischen HDL/LDL-ratio und fäkalen gesättigten FA
ggscatter(FA_stool.ST, x='sat', y='LDL_HDL_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations fecal [nmol/g]', ylab = 'LDL/HDL ratio')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='sat', y='LDL_HDL_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations fecal [nmol/g]', ylab = 'LDL/HDL ratio')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Plotten von Korrelationen zwischen LDL und fäkalen ungesättigten FA
ggscatter(FA_stool.ST, x='unsat', y='LDL',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations fecal [nmol/g]', ylab = 'LDL Concentration [mg/dl]')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='unsat', y='LDL', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations fecal [nmol/g]', ylab = 'LDL Concentration [mg/dl]')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Plotten von Korrelationen zwischen HDL und fäkalen ungesättigten FA
ggscatter(FA_stool.ST, x='unsat', y='HDL',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations fecal [nmol/g]', ylab = 'HDL Concentration [mg/dl]')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='unsat', y='HDL', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations fecal [nmol/g]', ylab = 'HDL Concentration [mg/dl]')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Plotten von Korrelationen zwischen HDL/LDL-ratio und fäkalen ungesättigten FA
ggscatter(FA_stool.ST, x='unsat', y='LDL_HDL_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations fecal [nmol/g]', ylab = 'LDL/HDL ratio')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='unsat', y='LDL_HDL_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations fecal [nmol/g]', ylab = 'LDL/HDL ratio')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Plotten von Korrelationen zwischen LDL und aufgenommenen gesättigten FA
ggscatter(FA_stool.ST, x='sat.i', y='LDL',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations intake [g]', ylab = 'LDL Concentration [mg/dl]')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='sat.i', y='LDL', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations intake [g]', ylab = 'LDL Concentration [mg/dl]')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Plotten von Korrelationen zwischen HDL und aufgenommenen gesättigten FA
ggscatter(FA_stool.ST, x='sat.i', y='HDL',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations intake [g]', ylab = 'HDL Concentration [mg/dl]')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='sat.i', y='HDL', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations intake [g]', ylab = 'HDL Concentration [mg/dl]')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Plotten von Korrelationen zwischen LDL/HDL-ratio und aufgenommenen gesättigten FA
ggscatter(FA_stool.ST, x='sat.i', y='LDL_HDL_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations intake [g]', ylab = 'LDL/HDL ratio')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='sat.i', y='LDL_HDL_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Saturated fatty acids concentrations intake [g]', ylab = 'LDL/HDL ratio')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Plotten von Korrelationen zwischen LDL und aufgenommenen ungesättigten FA
ggscatter(FA_stool.ST, x='unsat.i', y='LDL',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations intake [g]', ylab = 'LDL Concentration [mg/dl]')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='unsat.i', y='LDL', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations intake [g]', ylab = 'LDL Concentration [mg/dl]')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Plotten von Korrelationen zwischen HDL und aufgenommenen ungesättigten FA
ggscatter(FA_stool.ST, x='unsat.i', y='HDL',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations intake [g]', ylab = 'HDL Concentration [mg/dl]')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='unsat.i', y='HDL', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations intake [g]', ylab = 'HDL Concentration [mg/dl]')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Plotten von Korrelationen zwischen LDL/HDL-ratio und aufgenommenen ungesättigten FA
ggscatter(FA_stool.ST, x='unsat.i', y='LDL_HDL_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations intake [g]', ylab = 'LDL/HDL ratio')+
facet_grid(.~ Time, scales="free")+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(FA_stool.ST, x='unsat.i', y='LDL_HDL_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Unsaturated fatty acids concentrations intake [g]', ylab = 'LDL/HDL ratio')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
Wilcoxon-Test Unterschiede in LDL und HDL-Konzentrationen zwischen den Sättigungstypen
pairwise.wilcox.test(subset(filter(FA_stool.ST, Time == "PRE"))$LDL, subset(filter(FA_stool.ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Time == "POST"))$LDL, subset(filter(FA_stool.ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Time == "PRE"))$HDL, subset(filter(FA_stool.ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Time == "POST"))$HDL, subset(filter(FA_stool.ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "sat"))$LDL, subset(filter(FA_stool.ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired =F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "unsat"))$LDL, subset(filter(FA_stool.ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired= F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "change.sat"))$LDL, subset(filter(FA_stool.ST, Phenotype == "change.sat"))$Time, p.adjust.method = 'BH', paired =T)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "change.unsat"))$LDL, subset(filter(FA_stool.ST, Phenotype == "change.unsat"))$Time, p.adjust.method = 'BH', paired= F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "sat"))$HDL, subset(filter(FA_stool.ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired =F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "unsat"))$HDL, subset(filter(FA_stool.ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired= F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "change.sat"))$HDL, subset(filter(FA_stool.ST, Phenotype == "change.sat"))$Time, p.adjust.method = 'BH', paired =T)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "change.unsat"))$HDL, subset(filter(FA_stool.ST, Phenotype == "change.unsat"))$Time, p.adjust.method = 'BH', paired= F)
Plotten der Unterschiede
FA_stool.ST$Time <- factor(FA_stool.ST$Time, levels = c("PRE", "POST"))
ggplot(subset(filter(FA_stool.ST)), aes(x=Phenotype, y=LDL)) + xlab('Phenotype') + ylab('LDL concentration [mg/dl]') +
geom_boxplot(fill='whitesmoke', color='black') +
geom_dotplot(binaxis= 'y', stackdir = 'center', dotsize = 0.3, fill = 'grey22', color='grey22') +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat) + facet_wrap(~Time)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(subset(filter(FA_stool.ST)), aes(x=Phenotype, y=HDL)) + xlab('Phenotype') + ylab('HDL concentration [mg/dl]') +
geom_boxplot(fill='whitesmoke', color='black') +
geom_dotplot(binaxis= 'y', stackdir = 'center', dotsize = 0.3, fill = 'grey22', color='grey22') +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat) + facet_wrap(~Time)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(subset(filter(FA_stool.ST)), aes(x=Phenotype, y=LDL_HDL_ratio)) + xlab('Phenotype') + ylab('LDL/HDL ratio') +
geom_boxplot(fill='whitesmoke', color='black') +
geom_dotplot(binaxis= 'y', stackdir = 'center', dotsize = 0.3, fill = 'grey22', color='grey22') +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat) + facet_wrap(~Time)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(subset(filter(FA_stool.ST)), aes(x=Time, y=LDL)) + xlab('Time Point') +
ylab('LDL concentration [mg/dl]') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color= 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = F, aes(label= ..p.signif..), comparisons = comparison_time)
ggplot(subset(filter(FA_stool.ST)), aes(x=Time, y=HDL)) + xlab('Time Point') +
ylab('HDL concentration [mg/dl]') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color= 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = F, aes(label= ..p.signif..), comparisons = comparison_time)
ggplot(subset(filter(FA_stool.ST)), aes(x=Time, y=LDL_HDL_ratio)) + xlab('Time Point') +
ylab('LDL/HDL ratio') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color= 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = F, aes(label= ..p.signif..), comparisons = comparison_time)
Testen der signifikanten Unterschiede der Fettsäurenausscheidung der Sättigungstypen Laden und filtern der Metadaten
FA_stool.ST <- read.table("/Users/student05/Documents/fa saturation mit intake types.txt", sep = '\t', comment='',
head=T)
View(FA_stool)
FA_stool.ST$Time <-factor(FA_stool.ST$Time, levels = c("PRE", "POST"))
row.names(FA_stool.ST) <- FA_stool.ST$SampleID
FA_stool.ST$Proband
FA_stool.ST <- subset(filter(FA_stool.ST, !SampleID == "ST.35AD.0U1"))
FA_stool.ST <- subset(filter(FA_stool.ST, !Proband == "33MP", !Proband == "35AD", !Proband == "34WF", !Proband == "49RJ"))
comparison_sat <- list(c("sat", "unsat"))
comparison_change <- list(c("change.sat", "change.unsat"))
comparison_time <- list(c("PRE", "POST"))
Wilcoxon Test Unterschiede fäkaler Fettsäurekonzentrationen zwischen Sättigungstypen
pairwise.wilcox.test(subset(filter(FA_stool.ST, Time == "PRE"))$sat, subset(filter(FA_stool.ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Time == "POST"))$sat, subset(filter(FA_stool.ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Time == "PRE"))$unsat, subset(filter(FA_stool.ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Time == "POST"))$unsat, subset(filter(FA_stool.ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "sat"))$sat, subset(filter(FA_stool.ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired =F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "unsat"))$sat, subset(filter(FA_stool.ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired= F)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "change.sat"))$sat, subset(filter(FA_stool.ST, Phenotype == "change.sat"))$Time, p.adjust.method = 'BH', paired =T)
pairwise.wilcox.test(subset(filter(FA_stool.ST, Phenotype == "change.unsat"))$sat, subset(filter(FA_stool.ST, Phenotype == "change.unsat"))$Time, p.adjust.method = 'BH', paired= F)
Plotten der Unterschiede
ggplot(subset(filter(FA_stool.ST)), aes(x=Phenotype, y=sat)) + xlab('Phenotype') + ylab('Saturated fatty acid Concentration [nmol/g DW]') +
geom_boxplot(fill='whitesmoke', color='black') +
geom_dotplot(binaxis= 'y', stackdir = 'center', dotsize = 0.3, fill = 'grey22', color='grey22') +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat) + facet_wrap(~Time)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(subset(filter(FA_stool.ST)), aes(x=Phenotype, y=unsat)) + xlab('Phenotype') + ylab('Unsaturated fatty acid Concentration [nmol/g DW]') +
geom_boxplot(fill='whitesmoke', color='black') +
geom_dotplot(binaxis= 'y', stackdir = 'center', dotsize = 0.3, fill = 'grey22', color='grey22') +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat) + facet_wrap(~Time)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(subset(filter(FA_stool.ST)), aes(x=Time, y=sat)) + xlab('Time Point') +
ylab('Saturated fatty acid Concentration [nmol/g DW]') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color= 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = F, aes(label= ..p.signif..), comparisons = comparison_time)
ggplot(subset(filter(FA_stool.ST)), aes(x=Time, y=unsat)) + xlab('Time Point') +
ylab('Unaturated fatty acid Concentration [nmol/g DW]') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color= 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = F, aes(label= ..p.signif..), comparisons = comparison_time)
Bestimmen der means und SD
mean(subset(filter(FA_stool.ST, Time == "PRE" & Phenotype == "sat"))$sat)
sd(subset(filter(FA_stool.ST, Time == "PRE" & Phenotype == "sat"))$sat)
mean(subset(filter(FA_stool.ST, Time == "POST" & Phenotype == "sat"))$sat)
sd(subset(filter(FA_stool.ST, Time == "POST" & Phenotype == "sat"))$sat)
mean(subset(filter(FA_stool.ST, Time == "PRE" & Phenotype == "unsat"))$sat)
sd(subset(filter(FA_stool.ST, Time == "PRE" & Phenotype == "unsat"))$sat)
mean(subset(filter(FA_stool.ST, Time == "POST" & Phenotype == "unsat"))$sat)
sd(subset(filter(FA_stool.ST, Time == "POST" & Phenotype == "unsat"))$sat)
mean(subset(filter(FA_stool.ST, Time == "PRE" & Phenotype == "sat"))$unsat)
sd(subset(filter(FA_stool.ST, Time == "PRE" & Phenotype == "sat"))$unsat)
mean(subset(filter(FA_stool.ST, Time == "POST" & Phenotype == "sat"))$unsat)
sd(subset(filter(FA_stool.ST, Time == "POST" & Phenotype == "sat"))$unsat)
mean(subset(filter(FA_stool.ST, Time == "PRE" & Phenotype == "unsat"))$unsat)
sd(subset(filter(FA_stool.ST, Time == "PRE" & Phenotype == "unsat"))$unsat)
mean(subset(filter(FA_stool.ST, Time == "POST" & Phenotype == "unsat"))$unsat)
sd(subset(filter(FA_stool.ST, Time == "POST" & Phenotype == "unsat"))$unsat)
Testen von Unterschiede im relativen Vorkommen der Taxa zwischen den Sättigungstypen Laden der Phylum-Metadaten s.o. Synchronisieren der Daten, hinzufügen von log-Transformation und Pseudocount 0.00001
relab_phylum_ID <- relab_phylum_spread
relab_phylum_ID <- mutate(relab_phylum_ID, SampleID = paste(Proband, Time,sep="."))
row.names(relab_phylum_ID) <- relab_phylum_ID$SampleID
relab_genus_ID <- relab_genus_spread
relab_genus_ID <- mutate(relab_genus_ID, SampleID = paste(Proband, Time, sep ="."))
row.names(relab_genus_ID) <- relab_genus_ID$SampleID
FA_stool <- subset(filter(FA_stool, !Proband == "31KE", !Proband == "34WF",
!Proband == "45GL", !Proband == "49RJ", !Proband == "54SL", !Proband == "74SA"))
FA_stool.ST <- mutate(FA_stool.ST, SampleID1 = paste(Proband, Time, sep = "."))
row.names(FA_stool.ST) <- FA_stool.ST$SampleID1
common.ids.relab <- intersect(rownames(FA_stool.ST), rownames(relab_phylum_ID))
FA_stool.ST <- FA_stool.ST[common.ids.relab,]
relab_phylum_ID <- relab_phylum_ID[common.ids.relab,]
relab_genus_ID <- relab_genus_ID[common.ids.relab,]
relab_phylum_ID1 <- relab_phylum_ID[,c(3:8)] + 0.00001
relab_phylum_ID_log <- log10(relab_phylum_ID_log)
phylum_ST <- cbind(relab_phylum_ID1, FA_stool.ST)
write.table(phylum_ST, file = '/Users/student05/Documents/fa feces/FA fecal/saturation types/phylum-phenotype.txt', sep = "\t", col.names = TRUE,row.names = FALSE)
Wilcoxon-Test zur Bestimmung von Unterschiede im relativen Vorkommen der Phyla zwischen Sättigungstypen
Firmicutes
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "PRE"))$k__Bacteria.p__Firmicutes, subset(filter(phylum_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "POST"))$k__Bacteria.p__Firmicutes, subset(filter(phylum_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "sat"))$k__Bacteria.p__Firmicutes, subset(filter(phylum_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "unsat"))$k__Bacteria.p__Firmicutes, subset(filter(phylum_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "change.sat"))$k__Bacteria.p__Firmicutes, subset(filter(phylum_ST, Phenotype == "change.sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "change.unsat"))$k__Bacteria.p__Firmicutes, subset(filter(phylum_ST, Phenotype == "change.unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "sat"))$k__Bacteria.p__Firmicutes, subset(filter(phylum_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "unsat"))$k__Bacteria.p__Firmicutes, subset(filter(phylum_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
ggplot(subset(filter(phylum_ST)), aes(x=Phenotype,y=k__Bacteria.p__Firmicutes)) + xlab('Phenotype') + ylab('log10 (Relative Abundance p__Firmicutes)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)
ggplot(subset(filter(phylum_ST)), aes(x=Time,y=k__Bacteria.p__Firmicutes)) + xlab('Time') + ylab('log10 (Relative Abundance p__Firmicutes)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
Actinobacteria
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "PRE"))$k__Bacteria.p__Actinobacteria, subset(filter(phylum_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "POST"))$k__Bacteria.p__Actinobacteria, subset(filter(phylum_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
ggplot(subset(filter(phylum_ST)), aes(x=Phenotype,y=k__Bacteria.p__Actinobacteria)) + xlab('Phenotype') + ylab('log10 (Relative Abundance p__Actinobacteria)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(subset(filter(phylum_ST)), aes(x=Time,y=k__Bacteria.p__Actinobacteria)) + xlab('Time') + ylab('log10 (Relative Abundance p__Actinobacteria)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
phylum_ST$k__Bacteria.p__Actinobacteria
Bacteroidetes In Arbeit
mean(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "sat"))$k__Bacteria.p__Bacteroidetes)
sd(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "sat"))$k__Bacteria.p__Bacteroidetes)
mean(subset(filter(phylum_ST, Time == "POST" & Phenotype == "sat"))$k__Bacteria.p__Bacteroidetes)
sd(subset(filter(phylum_ST, Time == "POST" & Phenotype == "sat"))$k__Bacteria.p__Bacteroidetes)
mean(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "change.sat"))$k__Bacteria.p__Bacteroidetes)
sd(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "change.sat"))$k__Bacteria.p__Bacteroidetes)
mean(subset(filter(phylum_ST, Time == "POST" & Phenotype == "change.sat"))$k__Bacteria.p__Bacteroidetes)
sd(subset(filter(phylum_ST, Time == "POST" & Phenotype == "change.sat"))$k__Bacteria.p__Bacteroidetes)
mean(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "unsat"))$k__Bacteria.p__Bacteroidetes)
sd(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "unsat"))$k__Bacteria.p__Bacteroidetes)
mean(subset(filter(phylum_ST, Time == "POST" & Phenotype == "unsat"))$k__Bacteria.p__Bacteroidetes)
sd(subset(filter(phylum_ST, Time == "POST" & Phenotype == "unsat"))$k__Bacteria.p__Bacteroidetes)
mean(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "change.unsat"))$k__Bacteria.p__Bacteroidetes)
sd(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "change.unsat"))$k__Bacteria.p__Bacteroidetes)
mean(subset(filter(phylum_ST, Time == "POST" & Phenotype == "change.unsat"))$k__Bacteria.p__Bacteroidetes)
sd(subset(filter(phylum_ST, Time == "POST" & Phenotype == "change.unsat"))$k__Bacteria.p__Bacteroidetes)
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "PRE"))$k__Bacteria.p__Bacteroidetes, subset(filter(phylum_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "POST"))$k__Bacteria.p__Bacteroidetes, subset(filter(phylum_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "sat"))$k__Bacteria.p__Bacteroidetes, subset(filter(phylum_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "unsat"))$k__Bacteria.p__Bacteroidetes, subset(filter(phylum_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "change.sat"))$k__Bacteria.p__Bacteroidetes, subset(filter(phylum_ST, Phenotype == "change.sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "change.unsat"))$k__Bacteria.p__Bacteroidetes, subset(filter(phylum_ST, Phenotype == "change.unsat"))$Time, p.adjust.method = 'BH', paired = F)
library(scales)
pdf("/Users/student05/Documents/fertige Plots/sat.types.bacteroidetes.neu.pdf",width=8, height=10)
ggplot(subset(filter(phylum_ST)), aes(x=Phenotype,y=k__Bacteria.p__Bacteroidetes, fill= Phenotype)) +
xlab('Phenotype') + ylab('Relatives Vorkommen p__Bacteroidetes [%]') +
geom_boxplot(width = .7, lwd=0.6) + theme_classic()+
scale_x_discrete(labels=c("change.sat" = "zu gesättigt", "change.unsat" = "zu ungesättigt", "sat" = "gesättigt", "unsat"= "ungesättigt"))+
scale_fill_manual(labels = c("wechsel zu gesättigt", "wechsel zu ungesättigt", "gesättigt", "ungesättigt"),
values = c("lightskyblue4", "lightskyblue3", "lightskyblue2", "lightskyblue"))+
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)+
theme(legend.position="none")+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=45, hjust=1))+
scale_y_log10(labels = percent_format())
dev.off()
ggplot(subset(filter(phylum_ST)), aes(x=Time,y=k__Bacteria.p__Bacteroidetes)) + xlab('Time') + ylab('log10 (Relative Abundance p__Bacteroidetes)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
Proteobacteria
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "PRE"))$k__Bacteria.p__Proteobacteria, subset(filter(phylum_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "POST"))$k__Bacteria.p__Proteobacteria, subset(filter(phylum_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
ggplot(subset(filter(phylum_ST)), aes(x=Phenotype,y=k__Bacteria.p__Proteobacteria)) + xlab('Phenotype') + ylab('log10 (Relative Abundance p__Proteobacteria)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)
ggplot(subset(filter(phylum_ST)), aes(x=Time,y=k__Bacteria.p__Proteobacteria)) + xlab('Time') + ylab('log10 (Relative Abundance p__Proteobacteria)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
Tenericutes
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "PRE"))$k__Bacteria.p__Tenericutes, subset(filter(phylum_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "POST"))$k__Bacteria.p__Tenericutes, subset(filter(phylum_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
ggplot(subset(filter(phylum_ST)), aes(x=Phenotype,y=k__Bacteria.p__Tenericutes)) + xlab('Phenotype') + ylab('log10 (Relative Abundance p__Tenericutes)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)
ggplot(subset(filter(phylum_ST)), aes(x=Time,y=k__Bacteria.p__Tenericutes)) + xlab('Time') + ylab('log10 (Relative Abundance p__Tenericutes)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
Verrucomicrobia In Arbeit
mean(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "sat"))$k__Bacteria.p__Verrucomicrobia)
sd(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "sat"))$k__Bacteria.p__Verrucomicrobia)
mean(subset(filter(phylum_ST, Time == "POST" & Phenotype == "sat"))$k__Bacteria.p__Verrucomicrobia)
sd(subset(filter(phylum_ST, Time == "POST" & Phenotype == "sat"))$k__Bacteria.p__Verrucomicrobia)
mean(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "change.sat"))$k__Bacteria.p__Verrucomicrobia)
sd(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "change.sat"))$k__Bacteria.p__Verrucomicrobia)
mean(subset(filter(phylum_ST, Time == "POST" & Phenotype == "change.sat"))$k__Bacteria.p__Verrucomicrobia)
sd(subset(filter(phylum_ST, Time == "POST" & Phenotype == "change.sat"))$k__Bacteria.p__Verrucomicrobia)
mean(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "unsat"))$k__Bacteria.p__Verrucomicrobia)
sd(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "unsat"))$k__Bacteria.p__Verrucomicrobia)
mean(subset(filter(phylum_ST, Time == "POST" & Phenotype == "unsat"))$k__Bacteria.p__Verrucomicrobia)
sd(subset(filter(phylum_ST, Time == "POST" & Phenotype == "unsat"))$k__Bacteria.p__Verrucomicrobia)
mean(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "change.unsat"))$k__Bacteria.p__Verrucomicrobia)
sd(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "change.unsat"))$k__Bacteria.p__Verrucomicrobia)
mean(subset(filter(phylum_ST, Time == "POST" & Phenotype == "change.unsat"))$k__Bacteria.p__Verrucomicrobia)
sd(subset(filter(phylum_ST, Time == "POST" & Phenotype == "change.unsat"))$k__Bacteria.p__Verrucomicrobia)
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "PRE"))$k__Bacteria.p__Verrucomicrobia, subset(filter(phylum_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "POST"))$k__Bacteria.p__Verrucomicrobia, subset(filter(phylum_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "sat"))$k__Bacteria.p__Verrucomicrobia, subset(filter(phylum_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "unsat"))$k__Bacteria.p__Verrucomicrobia, subset(filter(phylum_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "change.sat"))$k__Bacteria.p__Verrucomicrobia, subset(filter(phylum_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "change.unsat"))$k__Bacteria.p__Verrucomicrobia, subset(filter(phylum_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
ggplot(subset(filter(phylum_ST)), aes(x=Phenotype,y=10^k__Bacteria.p__Verrucomicrobia)) + xlab('Phenotype') + ylab('log10 (Relative Abundance p__Verrucomicrobia)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
scale_y_log10(labels = percent_format())
ggplot(subset(filter(phylum_ST)), aes(x=Phenotype,y=10^k__Bacteria.p__Bacteroidetes)) + xlab('Phenotype') + ylab('log10 (Relative Abundance p__Bacteroidetes)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1)) +
scale_y_log10(labels = percent_format())
ggplot(subset(filter(phylum_ST)), aes(x=Time,y=k__Bacteria.p__Verrucomicrobia)) + xlab('Time') + ylab('log10 (Relative Abundance p__Verrucomicrobia)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
pdf("/Users/student05/Documents/fertige Plots/sat.types.verrucomicrobia.neu.pdf",width=8, height=10)
ggplot(subset(filter(phylum_ST)), aes(x=Phenotype,y=k__Bacteria.p__Verrucomicrobia, fill= Phenotype)) +
xlab('Phenotype') + ylab('Relatives Vorkommen p__Verrucomicrobia [%]') +
geom_boxplot(width = .7, lwd=0.6) + theme_classic()+
scale_x_discrete(labels=c("change.sat" = "zu gesättigt", "change.unsat" = "zu ungesättigt", "sat" = "gesättigt", "unsat"= "ungesättigt"))+
scale_fill_manual(labels = c("wechsel zu gesättigt", "wechsel zu ungesättigt", "gesättigt", "ungesättigt"),
values = c("lightskyblue4", "lightskyblue3", "lightskyblue2", "lightskyblue"))+
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = )+
theme(legend.position="none")+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=45, hjust=1))+
scale_y_log10(labels = percent_format())
dev.off()
Laden der Genus-Metadaten s.o. Synchronisieren der Daten, hinzufügen von log-Transformation und Pseudocount 0.00001
common.ids.relab <- intersect(rownames(FA_stool.ST), rownames(relab_genus_ID))
FA_stool.ST <- FA_stool.ST[common.ids.relab,]
relab_genus_ID <- relab_genus_ID[common.ids.relab,]
relab_genus_ID <- relab_genus_ID[common.ids.relab,]
relab_genus_ID1 <- relab_genus_ID[,c(3:31)] + 0.00001
relab_genus_ID_log <- log10(relab_genus_ID_log)
genus_ST <- cbind(relab_genus_ID1, FA_stool.ST)
Wilcoxon-Test zur Bestimmung von Unterschiede im relativen Vorkommen der Gattungen zwischen Sättigungstypen
Bifidobacterium
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "sat"))$k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, subset(filter(genus_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "unsat"))$k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, subset(filter(genus_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "PRE"))$k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, subset(filter(phylum_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "POST"))$k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium, subset(filter(phylum_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired=FALSE)
ggplot(subset(filter(genus_ST)), aes(x=Phenotype,y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium)) + xlab('Phenotype') + ylab('log10 (Relative Abundance g__Bifidobacterium)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(subset(filter(genus_ST)), aes(x=Time,y=k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium)) + xlab('Time') + ylab('log10 (Relative Abundance g__Bifidobacterium)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
Faecalibacterium
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "sat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium, subset(filter(genus_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "unsat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium, subset(filter(genus_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "PRE"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium, subset(filter(phylum_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "POST"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium, subset(filter(phylum_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired=FALSE)
ggplot(subset(filter(genus_ST)), aes(x=Phenotype,y=10^k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium)) + xlab('Phenotype') + ylab('log10 (Relative Abundance g__Faecalibacterium)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
scale_y_log10(labels = percent_format())
ggplot(subset(filter(genus_ST)), aes(x=Time,y=10^k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium)) + xlab('Time') + ylab('log10 (Relative Abundance g__Faecalibacterium)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)+
scale_y_log10(labels = percent_format())
Sutterella
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "sat"))$k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella, subset(filter(genus_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "unsat"))$k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella, subset(filter(genus_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "PRE"))$k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella, subset(filter(phylum_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "POST"))$k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella, subset(filter(phylum_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired=FALSE)
ggplot(subset(filter(genus_ST)), aes(x=Phenotype,y=k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella)) + xlab('Phenotype') + ylab('log10 (Relative Abundance g__Sutterella)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)
ggplot(subset(filter(genus_ST)), aes(x=Time,y=k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella)) + xlab('Time') + ylab('log10 (Relative Abundance g__Sutterella)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
Oscillospira In Arbeit
mean(subset(filter(genus_ST, Time == "PRE" & Phenotype == "sat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
sd(subset(filter(genus_ST, Time == "PRE" & Phenotype == "sat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
mean(subset(filter(genus_ST, Time == "POST" & Phenotype == "sat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
sd(subset(filter(genus_ST, Time == "POST" & Phenotype == "sat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
mean(subset(filter(genus_ST, Time == "PRE" & Phenotype == "change.sat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
sd(subset(filter(genus_ST, Time == "PRE" & Phenotype == "change.sat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
mean(subset(filter(genus_ST, Time == "POST" & Phenotype == "change.sat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
sd(subset(filter(genus_ST, Time == "POST" & Phenotype == "change.sat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
mean(subset(filter(genus_ST, Time == "PRE" & Phenotype == "unsat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
sd(subset(filter(genus_ST, Time == "PRE" & Phenotype == "unsat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
mean(subset(filter(genus_ST, Time == "POST" & Phenotype == "unsat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
sd(subset(filter(genus_ST, Time == "POST" & Phenotype == "unsat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
mean(subset(filter(genus_ST, Time == "PRE" & Phenotype == "change.unsat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
sd(subset(filter(genus_ST, Time == "PRE" & Phenotype == "change.unsat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
mean(subset(filter(genus_ST, Time == "POST" & Phenotype == "change.unsat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
sd(subset(filter(genus_ST, Time == "POST" & Phenotype == "change.unsat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "sat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, subset(filter(genus_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "unsat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, subset(filter(genus_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "change.sat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, subset(filter(genus_ST, Phenotype == "change.sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "change.unsat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, subset(filter(genus_ST, Phenotype == "change.unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "PRE"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, subset(filter(phylum_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "POST"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, subset(filter(phylum_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired=FALSE)
ggplot(subset(filter(genus_ST)), aes(x=Phenotype,y=10^k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)) + xlab('Phenotype') + ylab('log10 (Relative Abundance g__Oscillospira)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
scale_y_log10(labels = percent_format())
pdf("/Users/student05/Documents/fertige Plots/sat.types.oscillo.neu.pdf",width=8, height=10)
ggplot(subset(filter(genus_ST)), aes(x=Phenotype,y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira, fill= Phenotype)) +
xlab('Phänotyp') + ylab('Relatives Vorkommen g__Oscillospira [%]') +
geom_boxplot(width = .7, lwd=0.6) + theme_classic()+
scale_x_discrete(labels=c("change.sat" = "zu gesättigt", "change.unsat" = "zu ungesättigt", "sat" = "gesättigt", "unsat"= "ungesättigt"))+
scale_fill_manual(labels = c("wechsel zu gesättigt", "wechsel zu ungesättigt", "gesättigt", "ungesättigt"),
values = c("lightskyblue4", "lightskyblue3", "lightskyblue2", "lightskyblue"))+
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)+
theme(legend.position="none")+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=45, hjust=1))+
scale_y_log10(labels = percent_format())
dev.off()
ggplot(subset(filter(genus_ST)), aes(x=Time,y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira)) + xlab('Time') + ylab('log10 (Relative Abundance g__Oscillospira)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
Akkermansia In Arbeit
mean(subset(filter(genus_ST, Time == "PRE" & Phenotype == "sat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
sd(subset(filter(genus_ST, Time == "PRE" & Phenotype == "sat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
mean(subset(filter(genus_ST, Time == "POST" & Phenotype == "sat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
sd(subset(filter(genus_ST, Time == "POST" & Phenotype == "sat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
mean(subset(filter(genus_ST, Time == "PRE" & Phenotype == "change.sat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
sd(subset(filter(genus_ST, Time == "PRE" & Phenotype == "change.sat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
mean(subset(filter(genus_ST, Time == "POST" & Phenotype == "change.sat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
sd(subset(filter(genus_ST, Time == "POST" & Phenotype == "change.sat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
mean(subset(filter(genus_ST, Time == "PRE" & Phenotype == "unsat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
sd(subset(filter(genus_ST, Time == "PRE" & Phenotype == "unsat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
mean(subset(filter(genus_ST, Time == "POST" & Phenotype == "unsat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
sd(subset(filter(genus_ST, Time == "POST" & Phenotype == "unsat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
mean(subset(filter(genus_ST, Time == "PRE" & Phenotype == "change.unsat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
sd(subset(filter(genus_ST, Time == "PRE" & Phenotype == "change.unsat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
mean(subset(filter(genus_ST, Time == "POST" & Phenotype == "change.unsat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
sd(subset(filter(genus_ST, Time == "POST" & Phenotype == "change.unsat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "sat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, subset(filter(genus_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "unsat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, subset(filter(genus_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "change.sat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, subset(filter(genus_ST, Phenotype == "change.sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "change.unsat"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, subset(filter(genus_ST, Phenotype == "change.unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "PRE"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, subset(filter(phylum_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "POST"))$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, subset(filter(phylum_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired=FALSE)
ggplot(subset(filter(genus_ST)), aes(x=Phenotype,y=10^k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)) + xlab('Phenotype') + ylab('log10 (Relative Abundance g__Akkermansia)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)+
theme(legend.position="none")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
scale_y_log10(labels = percent_format())
pdf("/Users/student05/Documents/fertige Plots/sat.types.akkermansia.neu.pdf",width=8, height=10)
ggplot(subset(filter(genus_ST)), aes(x=Phenotype,y=k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia, fill= Phenotype)) +
xlab('Phänotyp') + ylab('Relatives Vorkommen g__Akkermansia [%]') +
geom_boxplot(width = .7, lwd=0.6) + theme_classic()+
scale_x_discrete(labels=c("change.sat" = "zu gesättigt", "change.unsat" = "zu ungesättigt", "sat" = "gesättigt", "unsat"= "ungesättigt"))+
scale_fill_manual(labels = c("wechsel zu gesättigt", "wechsel zu ungesättigt", "gesättigt", "ungesättigt"),
values = c("lightskyblue4", "lightskyblue3", "lightskyblue2", "lightskyblue"))+
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = )+
theme(legend.position="none")+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=45, hjust=1))+
scale_y_log10(labels = percent_format())
dev.off()
ggplot(subset(filter(genus_ST)), aes(x=Time,y=10^k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia)) + xlab('Time') + ylab('log10 (Relative Abundance g__Akkermansia)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)+
scale_y_log10(labels = percent_format())
Bacteroides
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "sat"))$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, subset(filter(genus_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "unsat"))$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, subset(filter(genus_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "PRE"))$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, subset(filter(genus_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "POST"))$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides, subset(filter(genus_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired=FALSE)
ggplot(subset(filter(genus_ST)), aes(x=Phenotype,y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides)) + xlab('Phenotype') + ylab('log10 (Relative Abundance g__Bacteroides)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)
ggplot(subset(filter(genus_ST)), aes(x=Time,y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides)) + xlab('Time') + ylab('log10 (Relative Abundance g__Bacteroides)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
Prevotella
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "sat"))$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella, subset(filter(genus_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "unsat"))$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella, subset(filter(genus_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "PRE"))$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella, subset(filter(genus_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "POST"))$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella, subset(filter(genus_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired=FALSE)
ggplot(subset(filter(genus_ST)), aes(x=Phenotype,y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella)) + xlab('Phenotype') + ylab('log10 (Relative Abundance g__Prevotella)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)
ggplot(subset(filter(genus_ST)), aes(x=Time,y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella)) + xlab('Time') + ylab('log10 (Relative Abundance g__Prevotella)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
Dorea
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "sat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea, subset(filter(genus_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "unsat"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea, subset(filter(genus_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "PRE"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea, subset(filter(genus_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "POST"))$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea, subset(filter(genus_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired=FALSE)
ggplot(subset(filter(genus_ST)), aes(x=Phenotype,y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea)) + xlab('Phenotype') + ylab('log10 (Relative Abundance g__Dorea)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)
ggplot(subset(filter(genus_ST)), aes(x=Time,y=k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea)) + xlab('Time') + ylab('log10 (Relative Abundance g__Dorea)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
Collinsella
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "sat"))$k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella, subset(filter(genus_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "unsat"))$k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella, subset(filter(genus_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "PRE"))$k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella, subset(filter(genus_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "POST"))$k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella, subset(filter(genus_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired=FALSE)
ggplot(subset(filter(genus_ST)), aes(x=Phenotype,y=k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella)) + xlab('Phenotype') + ylab('log10 (Relative Abundance g__Collinsella)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)
ggplot(subset(filter(genus_ST)), aes(x=Time,y=k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella)) + xlab('Time') + ylab('log10 (Relative Abundance g__Collinsella)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
Rikenellaceae
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "sat"))$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, subset(filter(genus_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Phenotype == "unsat"))$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, subset(filter(genus_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "PRE"))$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, subset(filter(genus_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = FALSE)
pairwise.wilcox.test(subset(filter(genus_ST, Time == "POST"))$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__, subset(filter(genus_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired=FALSE)
ggplot(subset(filter(genus_ST)), aes(x=Phenotype,y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__)) + xlab('Phenotype') + ylab('log10 (Relative Abundance f__Rikenellaceae)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)
ggplot(subset(filter(genus_ST)), aes(x=Time,y=k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Rikenellaceae.g__)) + xlab('Time') + ylab('log10 (Relative Abundance f__Rikenellaceae)') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
FA_stool.PRE <- subset(filter(FA_stool.ST, Time == "PRE"))
FA_stool.POST <- subset(filter(FA_stool.ST, Time == "POST"))
Unterschiede im Firmicutes/Bacteroidetes-ratio zwischen den Sättigungstypen
Laden der Metadaten, Bestimmen von Mean und SD
phylum_ST <- read.table("/Users/student05/Documents/fa feces/FA fecal/saturation types/phylum.phenotype.txt", sep ='\t', comment='', head=T)
phylum_ST$Time <-factor(phylum_ST$Time, levels = c("PRE", "POST"))
mean(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "sat"))$F_B_ratio)
sd(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "sat"))$F_B_ratio)
mean(subset(filter(phylum_ST, Time == "POST" & Phenotype == "sat"))$F_B_ratio)
sd(subset(filter(phylum_ST, Time == "POST" & Phenotype == "sat"))$F_B_ratio)
mean(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "change.sat"))$F_B_ratio)
sd(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "change.sat"))$F_B_ratio)
mean(subset(filter(phylum_ST, Time == "POST" & Phenotype == "change.sat"))$F_B_ratio)
sd(subset(filter(phylum_ST, Time == "POST" & Phenotype == "change.sat"))$F_B_ratio)
mean(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "unsat"))$F_B_ratio)
sd(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "unsat"))$F_B_ratio)
mean(subset(filter(phylum_ST, Time == "POST" & Phenotype == "unsat"))$F_B_ratio)
sd(subset(filter(phylum_ST, Time == "POST" & Phenotype == "unsat"))$F_B_ratio)
mean(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "change.unsat"))$F_B_ratio)
sd(subset(filter(phylum_ST, Time == "PRE" & Phenotype == "change.unsat"))$F_B_ratio)
mean(subset(filter(phylum_ST, Time == "POST" & Phenotype == "change.unsat"))$F_B_ratio)
sd(subset(filter(phylum_ST, Time == "POST" & Phenotype == "change.unsat"))$F_B_ratio)
Wilcoxon-Test zur Bestimmung von Unterschiede im F/B-ratio zwischen Sättigungstypen
In Arbeit
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "PRE"))$F_B_ratio, subset(filter(phylum_ST, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Time == "POST"))$F_B_ratio, subset(filter(phylum_ST, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "sat"))$F_B_ratio, subset(filter(phylum_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "unsat"))$F_B_ratio, subset(filter(phylum_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "change.sat"))$F_B_ratio, subset(filter(phylum_ST, Phenotype == "change.sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "change.unsat"))$F_B_ratio, subset(filter(phylum_ST, Phenotype == "change.unsat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "sat"))$F_B_ratio, subset(filter(phylum_ST, Phenotype == "sat"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(phylum_ST, Phenotype == "unsat"))$F_B_ratio, subset(filter(phylum_ST, Phenotype == "unsat"))$Time, p.adjust.method = 'BH', paired = F)
ggplot(subset(filter(phylum_ST)), aes(x=Phenotype,y=F_B_ratio)) + xlab('Phenotype') + ylab('Firmicutes/Bacteroidetes ratio') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
pdf("/Users/student05/Documents/fertige Plots/sat.types.F.B.pdf",width=8, height=10)
ggplot(subset(filter(phylum_ST)), aes(x=Phenotype,y=F_B_ratio, fill= Phenotype)) +
xlab('Phenotype') + ylab('Firmicutes/Bacteroidetes Verhältnis') +
geom_boxplot(width = .7, lwd=0.6) + theme_classic()+
scale_x_discrete(labels=c("change.sat" = "zu gesättigt", "change.unsat" = "zu ungesättigt", "sat" = "gesättigt", "unsat"= "ungesättigt"))+
scale_fill_manual(labels = c("wechsel zu gesättigt", "wechsel zu ungesättigt", "gesättigt", "ungesättigt"),
values = c("lightskyblue4", "lightskyblue3", "lightskyblue2", "lightskyblue"))+
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_sat)+
theme(legend.position="none")+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=45, hjust=1))
dev.off()
types <- melt(phylum_ST, id.vars = c('Time', 'F_B_ratio'), measure.vars = c('sat', 'unsat'))
types.pr <- subset(filter(types, !Time == 'POST'))
types.po <- subset(filter(types, !Time == 'PRE'))
types <-dplyr::rename(types, FA=variable)
types <- dplyr::rename(types, Concentration=value)
pairwise.wilcox.test(subset(filter(convT, Time == "PRE"))$F_B_ratio, subset(filter(convT, Time == "PRE"))$Phenotype2, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(convT, Time == "POST"))$F_B_ratio, subset(filter(convT, Time == "POST"))$Phenotype2, p.adjust.method = 'BH', paired = F)
ggscatter(types.pr, x='Concentration', y='F_B_ratio',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ FA)+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
phylum_ST$Time <- factor(phylum_ST$Time, levels = c("PRE", "POST"))
pdf("/Users/student05/Documents/fertige Plots/sat.bact.firm.pdf",width=8, height=10)
ggscatter(phylum_ST, x='sat', y='F_B_ratio',color = 'Time', palette = c('skyblue', 'orchid'), add = 'reg.line', size=2.5,cor.coef.coord =c(250, 19),cor.coef.size = 7,conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Gesättigte Fettsäurenkonzentrationen [nmol/g]', ylab = 'Firmicutes/Bacteroidetes Verhältnis')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
dev.off()
pdf("/Users/student05/Documents/fertige Plots/unsat.bact.firm.pdf",width=8, height=10)
ggscatter(phylum_ST, x='unsat', y='F_B_ratio',color = 'Time', palette = c('skyblue', 'orchid'), add = 'reg.line',size=2.5, cor.coef.coord =c(250, 19),cor.coef.size = 7,conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Ungesättigte Fettsäurenkonzentrationen [nmol/g]', ylab = 'Firmicutes/Bacteroidetes Verhältnis')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
dev.off()
ggscatter(types.po, x='Concentration', y='F_B_ratio',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(500, 6),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ FA)+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(types, x='Concentration', y='F_B_ratio',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(500, 16),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ FA)+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
- Analysen mit dem Firmicutes/Bacteroidetes-ratio Unterschiede im F/B-ratio zwischen Sterolkonvertierungstypen Unterteilen in high und low converter
lowconv <- filter(phylum_ST, Proband == "05AP" | Proband == "33MP"
| Proband == "38AR" | Proband == "40WA" | Proband == "41ML"
| Proband == "47OT" | Proband == "49RJ" | Proband == "50DM")
lowconv['Phenotype2'] = 'low converter'
highconv <- filter(phylum_ST, Proband == "06WT" | Proband == "07RW"
| Proband == "13BS" | Proband == "17SK" | Proband == "22WS"
| Proband == "25FE" | Proband == "26FB" | Proband == "29MK"
| Proband == "30HB" | Proband == "31KE" | Proband == "36ER"
| Proband == "45GL" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
highconv['Phenotype2'] = 'high converter'
highconv$Converter.Type <- NULL
lowconv$Converter.Type <- NULL
noconv <- filter(phylum_ST, Proband == "28HM" | Proband == "32FG"
| Proband == "34WF" | Proband == "35AD" | Proband == "37SD"
| Proband == "39DA" | Proband == "66DG" | Proband == "70PL")
noconv['Phenotype2'] = 'not classified'
noconv$Converter.Type <- NULL
convT <- data.frame()
convT <- bind_rows(lowconv, highconv, noconv)
comparison_conv <- list(c("low converter", "high converter"))
convT <- subset(filter(convT, !Phenotype2 == 'not classified'))
pairwise.wilcox.test(subset(filter(convT, Time == "PRE"))$F_B_ratio, subset(filter(convT, Time == "PRE"))$Phenotype2, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(convT, Time == "POST"))$F_B_ratio, subset(filter(convT, Time == "POST"))$Phenotype2, p.adjust.method = 'BH', paired = F)
ggplot(subset(filter(convT)), aes(x=Phenotype2,y=F_B_ratio)) + xlab('Phenotype') + ylab('Firmicutes/Bacteroidetes ratio') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Time) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_conv)+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
ggplot(subset(filter(convT)), aes(x=Time,y=F_B_ratio)) + xlab('Time') + ylab('Firmicutes/Bacteroidetes ratio') +
geom_boxplot(fill = 'whitesmoke', color="black") +
geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 0.2, fill = 'grey22', color = 'grey22') +
facet_wrap(~Phenotype2) +
stat_compare_means(paired = FALSE, aes(label = ..p.signif..), comparisons = comparison_time)
Korrelationsanalysen zwischen allen fäkalen Fettsäuren und dem F/B-ratio Loop und Plots zu gesättigte Fettsäuren und F/B-ratio In Arbeit
phylum_colnames <- colnames(phylum_ST[, c(3:9)])
corr_map_phylum_sat <- filter(phylum_ST, !is.na(sat))
corr_spearman_Phylum_sat <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_sat, !is.na(i))
y = tmp[,i]
x = tmp$sat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$sat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$sat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_sat)+1
corr_spearman_Phylum_sat[nrow,"FA"] <- "sat"
corr_spearman_Phylum_sat[nrow, "Phylum"] = i
corr_spearman_Phylum_sat[nrow, "p.value"] = p
corr_spearman_Phylum_sat[nrow, "rho"] = rho
corr_spearman_Phylum_sat[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_sat[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_sat[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_sat[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_sat$p.adjusted <- p.adjust(corr_spearman_Phylum_sat$p.value, method = "BH", n = 35)
corr_spearman_Phylum_sat$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_sat$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_sat$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_sat$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_sat <- filter(corr_spearman_Phylum_sat, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_sat, file = '/Users/student05/Documents/FB q-value/sat.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_ST, x='sat', y='F_B_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'saturated fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='sat', y='F_B_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'saturated fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
pdf("/Users/student05/Documents/fertige Plots/sat.bact.firm.pdf",width=8, height=10)
ggscatter(phylum_ST, x='sat', y='F_B_ratio',color = 'Time', palette = c('skyblue', 'orchid'), add = 'reg.line', cor.coef.coord =c(250, 19),cor.coef.size = 7,conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Gesättigte Fettsäurenkonzentrationen [nmol/g]', ylab = 'Firmicutes/Bacteroidetes Verhältnis')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
dev.off()
Loop und Plots zu ungesättigte Fettsäuren und F/B-ratio
phylum_colnames <- colnames(phylum_ST[, c(3:9)])
corr_map_phylum_unsat <- filter(phylum_ST, !is.na(unsat))
corr_spearman_Phylum_unsat <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_unsat, !is.na(i))
y = tmp[,i]
x = tmp$unsat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$unsat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$unsat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_unsat)+1
corr_spearman_Phylum_unsat[nrow,"FA"] <- "unsat"
corr_spearman_Phylum_unsat[nrow, "Phylum"] = i
corr_spearman_Phylum_unsat[nrow, "p.value"] = p
corr_spearman_Phylum_unsat[nrow, "rho"] = rho
corr_spearman_Phylum_unsat[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_unsat[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_unsat[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_unsat[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_unsat$p.adjusted <- p.adjust(corr_spearman_Phylum_unsat$p.value, method = "BH", n = 35)
corr_spearman_Phylum_unsat$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_unsat$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_unsat$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_unsat$p.value_POST, method = "BH", n = 35)
corr_sig_Phylum_unsat <- filter(corr_spearman_Phylum_unsat, p.adjusted < 0.05 | p.adjusted_PRE < 0.05 | p.adjusted_POST < 0.05)
write.table(corr_spearman_Phylum_unsat, file = '/Users/student05/Documents/FB q-value/unsat.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plots zu einfach ungesättigten FA und F/B-ratio
ggscatter(phylum_ST, x='mono.unsat', y='F_B_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Monounsaturated fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='mono.unsat', y='F_B_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Monounsaturated fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
Plots zu zweifach ungesättigten FA - total FA und F/B-ratio
ggscatter(phylum_ST, x='di.unsat', y='F_B_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Diunsaturated fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='di.unsat', y='F_B_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Diunsaturated fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='more.2.unsat', y='F_B_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '> 2 unsaturated fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='more.2.unsat', y='F_B_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '> 2 unsaturated fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='less.14', y='F_B_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '< 14 c atomes fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='more.2.unsat', y='F_B_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '> 2 unsaturated fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='c14.17', y='F_B_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= ' 14-17 c atomes fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='c14.17', y='F_B_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '> 14-17 c atomes fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='c18.19', y='F_B_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= ' 18-19 c atomes fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='c18.19', y='F_B_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '18-19 c atomes fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='c20.21', y='F_B_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= ' 20-21 c atomes fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='c20.21', y='F_B_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '20-21 c atomes fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='c22.24', y='F_B_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= ' 22-24 c atomes fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='c20.21', y='F_B_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= '20-21 c atomes fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='total', y='F_B_ratio',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= ' total fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_ST, x='total', y='F_B_ratio', add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'total fatty acid concentration [nmol/g]', ylab = 'Firmicutes/Bacteroidetes ratio')+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
5.2 Korrelationen gesättigte FA und ungesättigte FA mit phylum-level
Filtern der Phylum-Metadaten, hinzufügen von log-Transformation und Pseudocount 0.0001
phylum_ST_log <- phylum_ST[,c(3:8)] + 0.00001
phylum_ST_log <- log10(phylum_ST_log)
phylum_ST <- cbind(phylum_ST_log, phylum_ST[, c(9:33)])
phylum_colnames <- colnames(relab_phylum_spread[, c(3:8)])
corr_map_phylum_unsat <- filter(phylum_ST, !is.na(unsat))
corr_spearman_Phylum_unsat <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_unsat, !is.na(i))
y = tmp[,i]
x = tmp$unsat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time.1 == "PRE"))[,i]
w = subset(filter(tmp, Time.1 == "PRE"))$unsat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time.1 == "POST"))[,i]
s = subset(filter(tmp, Time.1 == "POST"))$unsat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_unsat)+1
corr_spearman_Phylum_unsat[nrow,"FA"] <- "unsat"
corr_spearman_Phylum_unsat[nrow, "Phylum"] = i
corr_spearman_Phylum_unsat[nrow, "p.value"] = p
corr_spearman_Phylum_unsat[nrow, "rho"] = rho
corr_spearman_Phylum_unsat[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_unsat[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_unsat[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_unsat[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_unsat$p.adjusted <- p.adjust(corr_spearman_Phylum_unsat$p.value, method = "BH", n = 35)
corr_spearman_Phylum_unsat$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_unsat$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_unsat$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_unsat$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_unsat, file = '/Users/student05/Documents/unsat.phylum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten der Korrelationen zwischen gesättigten und ungesättigten FA und phylum-level
Teilweise in Arbeit
phylum_ST$k__Bacteria.p__Firmicutes
melt.Fi <- melt(phylum_ST, id.vars = c('Time.1', 'k__Bacteria.p__Firmicutes'), measure.vars = c('sat', 'unsat'))
melt.Fi<-dplyr::rename(melt.Fi, FA=variable)
melt.Fi <- dplyr::rename(melt.Fi, Concentration=value)
melt.Fi.pr <- subset(filter(melt.Fi, !Time.1 == 'POST'))
melt.Fi.po <- subset(filter(melt.Fi, !Time.1 == 'PRE'))
melt.Fi.pr$k__Bacteria.p__Firmicutes
ggscatter(melt.Fi.pr, x='Concentration', y='k__Bacteria.p__Firmicutes',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(300, -0.7),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Firmicutes')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Fi.po, x='Concentration', y='k__Bacteria.p__Firmicutes',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(500, -0.75),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Firmicutes')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Fi, x='Concentration', y='k__Bacteria.p__Firmicutes',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(500, -0.7),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Firmicutes')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
phylum_ST$k__Bacteria.p__Bacteroidetes
melt.Ba <- melt(phylum_ST, id.vars = c('Time.1', 'k__Bacteria.p__Bacteroidetes'), measure.vars = c('sat', 'unsat'))
melt.Ba<-dplyr::rename(melt.Ba, FA=variable)
melt.Ba <- dplyr::rename(melt.Ba, Concentration=value)
melt.Ba.pr <- subset(filter(melt.Ba, !Time.1 == 'POST'))
melt.Ba.po <- subset(filter(melt.Ba, !Time.1 == 'PRE'))
ggscatter(melt.Ba.pr, x='Concentration', y='k__Bacteria.p__Bacteroidetes',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(300, -0.7),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Bacteroidetes')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Ba.po, x='Concentration', y='k__Bacteria.p__Bacteroidetes',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(500, -0.95),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Bacteroidetes')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Ba, x='Concentration', y='k__Bacteria.p__Bacteroidetes',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(500, -0.9),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Bacteroidetes')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
phylum_ST$Time.1 <- factor(phylum_ST$Time.1, levels = c("PRE", "POST"))
pdf("/Users/student05/Documents/fertige Plots/unsat.bacteroidetes.pdf",width=8, height=10)
ggscatter(phylum_ST, x='unsat', y='k__Bacteria.p__Bacteroidetes',color = 'Time.1', palette = c('skyblue', 'orchid'), add = 'reg.line', cor.coef.coord =c(0, -0.8),cor.coef.size = 7,conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Ungesättigte Fettsäurenkonzentrationen [nmol/g]', ylab = 'log10 (Relatives Vorkommen p__Bacteroidetes)')+
facet_grid(.~ Time.1, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=45, hjust=1))+
theme(legend.position="none")
dev.off()
phylum_ST$k__Bacteria.p__Verrucomicrobia
melt.Ve <- melt(phylum_ST, id.vars = c('Time.1', 'k__Bacteria.p__Verrucomicrobia'), measure.vars = c('sat', 'unsat'))
melt.Ve<-dplyr::rename(melt.Ve, FA=variable)
melt.Ve <- dplyr::rename(melt.Ve, Concentration=value)
melt.Ve.pr <- subset(filter(melt.Ve, !Time.1 == 'POST'))
melt.Ve.po <- subset(filter(melt.Ve, !Time.1 == 'PRE'))
ggscatter(melt.Ve.pr, x='Concentration', y='k__Bacteria.p__Verrucomicrobia',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(300, -0.7),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Verrucomicrobia')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Ve.po, x='Concentration', y='k__Bacteria.p__Verrucomicrobia',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(500, -0.3),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Verrucomicrobia')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Ve, x='Concentration', y='k__Bacteria.p__Verrucomicrobia',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -0.5),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Verrucomicrobia')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
phylum_ST$k__Bacteria.p__Tenericutes
melt.Te <- melt(phylum_ST, id.vars = c('Time.1', 'k__Bacteria.p__Tenericutes'), measure.vars = c('sat', 'unsat'))
melt.Te<-dplyr::rename(melt.Te, FA=variable)
melt.Te <- dplyr::rename(melt.Te, Concentration=value)
melt.Te.pr <- subset(filter(melt.Te, !Time.1 == 'POST'))
melt.Te.po <- subset(filter(melt.Te, !Time.1 == 'PRE'))
ggscatter(melt.Te.pr, x='Concentration', y='k__Bacteria.p__Tenericutes',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(350, -1.3),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Tenericutes')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Te.po, x='Concentration', y='k__Bacteria.p__Tenericutes',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(600, -1.3),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Tenericutes')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Te, x='Concentration', y='k__Bacteria.p__Tenericutes',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.5),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Tenericutes')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
phylum_ST$k__Bacteria.p__Actinobacteria
melt.Ac <- melt(phylum_ST, id.vars = c('Time.1', 'k__Bacteria.p__Actinobacteria'), measure.vars = c('sat', 'unsat'))
melt.Ac<-dplyr::rename(melt.Ac, FA=variable)
melt.Ac <- dplyr::rename(melt.Ac, Concentration=value)
t
melt.Ac.pr <- subset(filter(melt.Ac, !Time.1 == 'POST'))
melt.Ac.po <- subset(filter(melt.Ac, !Time.1 == 'PRE'))
ggscatter(melt.Ac.pr, x='Concentration', y='k__Bacteria.p__Actinobacteria',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(300, -1.3),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Actinobacteria')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Ac.po, x='Concentration', y='k__Bacteria.p__Actinobacteria',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(500, -1.4),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Actinobacteria')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Ac, x='Concentration', y='k__Bacteria.p__Actinobacteria',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.35),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Actinobacteria')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
phylum_ST$k__Bacteria.p__Proteobacteria
melt.Pr <- melt(phylum_ST, id.vars = c('Time.1', 'k__Bacteria.p__Proteobacteria'), measure.vars = c('sat', 'unsat'))
melt.Pr<-dplyr::rename(melt.Pr, FA=variable)
melt.Pr <- dplyr::rename(melt.Pr, Concentration=value)
melt.Pr.pr <- subset(filter(melt.Pr, !Time.1 == 'POST'))
melt.Pr.po <- subset(filter(melt.Pr, !Time.1 == 'PRE'))
ggscatter(melt.Pr.pr, x='Concentration', y='k__Bacteria.p__Proteobacteria',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(300, -1.6),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Proteobacteria')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Pr.po, x='Concentration', y='k__Bacteria.p__Proteobacteria',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(500, -1.6),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Proteobacteria')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Pr, x='Concentration', y='k__Bacteria.p__Proteobacteria',color = 'FA', palette = c('tomato', 'yellowgreen', 'steelblue2', 'deeppink2', 'cyan','yellow'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.35),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance p__Proteobacteria')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
5.3 Korrelationen gesättigte FA und ungesättigte FA mit genus-level
Filtern der Genus-Metadaten, hinzufügen von log-Transformation und Pseudocount 0.0001 Loop Genus-level
FA_stool.ST <- mutate(FA_stool.ST, SampleID1 = paste(Proband, Time, sep = "."))
row.names(FA_stool.ST) <- FA_stool.ST$SampleID1
genus_colnames <- colnames(relab_genus_spread[, c(3:31)])
common.ids.relab <- intersect(rownames(FA_stool.ST), rownames(relab_phylum_ID))
FA_stool.ST <- FA_stool.ST[common.ids.relab,]
relab_phylum_ID <- relab_phylum_ID[common.ids.relab,]
relab_genus_ID <- relab_genus_ID[common.ids.relab,]
relab_genus_ID_log <- relab_genus_ID[,c(3:31)] + 0.00001
relab_genus_ID_log <- log10(relab_genus_ID_log)
genus_FA <- cbind(relab_genus_ID_log, FA_stool.ST)
corr_map_genus_unsat <- filter(genus_FA, !is.na(unsat))
corr_spearman_genus_unsat <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_unsat, !is.na(i))
y = tmp[,i]
x = tmp$unsat
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$unsat
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$unsat
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_unsat)+1
corr_spearman_genus_unsat[nrow,"FA"] = "unsaturated"
corr_spearman_genus_unsat[nrow, "Genus"] = i
corr_spearman_genus_unsat[nrow, "p.value"] = p
corr_spearman_genus_unsat[nrow, "rho"] = rho
corr_spearman_genus_unsat[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_unsat[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_unsat[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_unsat[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_unsat$p.adjusted <- p.adjust(corr_spearman_genus_unsat$p.value, method = "BH", n = 35)
corr_spearman_genus_unsat$p.adjusted_PRE <- p.adjust(corr_spearman_genus_unsat$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_unsat$p.adjusted_POST <- p.adjust(corr_spearman_genus_unsat$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_genus_unsat, file = '/Users/student05/Documents/unsat.genus.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten der Korrelationen zwischen gesättigten und ungesättigten FA und genus-level
Teilweise in Arbeit
genus_FA$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira
pdf("/Users/student05/Documents/fertige Plots/unsat.oscillo.pdf",width=8, height=10)
ggscatter(genus_FA, x='unsat', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('skyblue', 'orchid'), add = 'reg.line', cor.coef.coord =c(0, -2),cor.coef.size = 7,conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Ungesättigte Fettsäurenkonzentrationen [nmol/g]', ylab = 'log10 (Relatives Vorkommen g__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
dev.off
melt.Os <- melt(genus_FA, id.vars = c('Time', 'k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira'), measure.vars = c('sat', 'unsat'))
melt.Os<-dplyr::rename(melt.Os, FA=variable)
melt.Os <- dplyr::rename(melt.Os, Concentration=value)
melt.Os.pr <- subset(filter(melt.Os, !Time == 'POST'))
melt.Os.po <- subset(filter(melt.Os, !Time == 'PRE'))
ggscatter(melt.Os.pr, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(300, -2),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Oscillospira')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Os.po, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -2),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Oscillospira')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Os, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -2),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Oscillospira')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
genus_FA$k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium
melt.Bi <- melt(genus_FA, id.vars = c('Time', 'k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium'), measure.vars = c('sat', 'unsat'))
melt.Bi<-dplyr::rename(melt.Bi, FA=variable)
melt.Bi <- dplyr::rename(melt.Bi, Concentration=value)
melt.Bi.pr <- subset(filter(melt.Bi, !Time == 'POST'))
melt.Bi.po <- subset(filter(melt.Bi, !Time == 'PRE'))
ggscatter(melt.Bi.pr, x='Concentration', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(300, -1.3),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Bifidobacterium')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Bi.po, x='Concentration', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.5),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Bifidobacterium')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Bi, x='Concentration', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.3),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Bifidobacterium')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
genus_FA$k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella
melt.Co <- melt(genus_FA, id.vars = c('Time', 'k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella'), measure.vars = c('sat', 'unsat'))
melt.Co<-dplyr::rename(melt.Co, FA=variable)
melt.Co <- dplyr::rename(melt.Co, Concentration=value)
melt.Co.pr <- subset(filter(melt.Co, !Time == 'POST'))
melt.Co.po <- subset(filter(melt.Co, !Time == 'PRE'))
ggscatter(melt.Co.pr, x='Concentration', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(300, -1.7),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Collinsella')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Co.po, x='Concentration', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.5),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Collinsella')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Co, x='Concentration', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.5),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Collinsella')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
genus_FA$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium
melt.Fa <- melt(genus_FA, id.vars = c('Time', 'k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium'), measure.vars = c('sat', 'unsat'))
melt.Fa<-dplyr::rename(melt.Fa, FA=variable)
melt.Fa <- dplyr::rename(melt.Fa, Concentration=value)
melt.Fa.pr <- subset(filter(melt.Fa, !Time == 'POST'))
melt.Fa.po <- subset(filter(melt.Fa, !Time == 'PRE'))
ggscatter(melt.Fa.pr, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(300, -1.3),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Faecalibacterium')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Fa.po, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.5),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Faecalibacterium')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Fa, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.5),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Faecalibacterium')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
genus_FA$k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia
melt.Ak <- melt(genus_FA, id.vars = c('Time', 'k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia'), measure.vars = c('sat', 'unsat'))
melt.Ak<-dplyr::rename(melt.Ak, FA=variable)
melt.Ak <- dplyr::rename(melt.Ak, Concentration=value)
melt.Ak.pr <- subset(filter(melt.Ak, !Time == 'POST'))
melt.Ak.po <- subset(filter(melt.Ak, !Time == 'PRE'))
ggscatter(melt.Ak.pr, x='Concentration', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(300, -1.3),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Akkermansia')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Ak.po, x='Concentration', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -0.6),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Akkermansia')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Ak, x='Concentration', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -0.6),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Akkermansia')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
genus_FA$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Blautia
melt.Bl <- melt(genus_FA, id.vars = c('Time', 'k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Blautia'), measure.vars = c('sat', 'unsat'))
melt.Bl<-dplyr::rename(melt.Bl, FA=variable)
melt.Bl <- dplyr::rename(melt.Bl, Concentration=value)
melt.Bl.pr <- subset(filter(melt.Bl, !Time == 'POST'))
melt.Bl.po <- subset(filter(melt.Bl, !Time == 'PRE'))
ggscatter(melt.Bl.pr, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Blautia',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(300, -1.7),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Blautia')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Bl.po, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Blautia',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.6),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Blautia')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Bl, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Blautia',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.6),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Blautia')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
genus_FA$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides
melt.Bc <- melt(genus_FA, id.vars = c('Time', 'k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides'), measure.vars = c('sat', 'unsat'))
melt.Bc<-dplyr::rename(melt.Bc, FA=variable)
melt.Bc <- dplyr::rename(melt.Bc, Concentration=value)
melt.Bc.pr <- subset(filter(melt.Bc, !Time == 'POST'))
melt.Bc.po <- subset(filter(melt.Bc, !Time == 'PRE'))
ggscatter(melt.Bc.pr, x='Concentration', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(200, -0.8),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Bacteroides')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Bc.po, x='Concentration', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.2),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Bacteroides')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Bc, x='Concentration', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Bacteroides')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
genus_FA$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus
melt.Cp <- melt(genus_FA, id.vars = c('Time', 'k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus'), measure.vars = c('sat', 'unsat'))
melt.Cp<-dplyr::rename(melt.Cp, FA=variable)
melt.Cp <- dplyr::rename(melt.Cp, Concentration=value)
melt.Cp.pr <- subset(filter(melt.Cp, !Time == 'POST'))
melt.Cp.po <- subset(filter(melt.Cp, !Time == 'PRE'))
ggscatter(melt.Cp.pr, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(200, -1.6),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Coprococcus')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Cp.po, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.5),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Coprococcus')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Cp, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.5),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Coprococcus')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
genus_FA$k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.
melt.Ru <- melt(genus_FA, id.vars = c('Time', 'k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.'), measure.vars = c('sat', 'unsat'))
melt.Ru<-dplyr::rename(melt.Ru, FA=variable)
melt.Ru <- dplyr::rename(melt.Ru, Concentration=value)
melt.Ru.pr <- subset(filter(melt.Ru, !Time == 'POST'))
melt.Ru.po <- subset(filter(melt.Ru, !Time == 'PRE'))
ggscatter(melt.Ru.pr, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(200, -2),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Ruminococcus')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Ru.po, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -2),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Ruminococcus')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Ru, x='Concentration', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -1.9),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Ruminococcus')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
genus_FA$k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella
melt.Pe <- melt(genus_FA, id.vars = c('Time', 'k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella'), measure.vars = c('sat', 'unsat'))
melt.Pe<-dplyr::rename(melt.Pe, FA=variable)
melt.Pe <- dplyr::rename(melt.Pe, Concentration=value)
melt.Pe.pr <- subset(filter(melt.Pe, !Time == 'POST'))
melt.Pe.po <- subset(filter(melt.Pe, !Time == 'PRE'))
ggscatter(melt.Pe.pr, x='Concentration', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(200, -0.6),cor.coef.size = 6, xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Prevotella')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('PRE')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Pe.po, x='Concentration', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -0.6),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Prevotella')+
facet_grid(.~ FA, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('POST')+
theme(plot.title = element_text(color="black", size=14))
ggscatter(melt.Pe, x='Concentration', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella',color = 'FA', palette = c('steelblue2', 'deeppink2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(300, -0.6),cor.coef.size = 6,xlab= 'Fatty acid concentration [nmol/g]', ylab = 'Relative Abundance g__Prevotella')+
facet_grid(.~ FA,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")+
ggtitle('Times together')+
theme(plot.title = element_text(color="black", size=14))
- Serumlipidanalyse
Laden der Daten und testen auf Normalverteilung
LI_serum <- read.table("/Users/student05/Documents/serum lipids zahlen.1-2.txt", sep = '\t', comment='',head=T)
LI_serum$Time <-factor(LI_serum$Time, levels = c("PRE", "POST"))
row.names(LI_serum) <- LI_serum$SampleID
nd.LI<- data_frame()
for (i in LI_colnames) {
fit <- shapiro.test(as.matrix(as.data.frame(lapply(LI_serum[,i],as.numeric))))
p = fit$p.value
nrow = nrow(nd.LI)+1
nd.LI[nrow, "column"] = i
nd.LI[nrow, "p.value"] = round(p, 4)
}
ggqqplot(LI_serum$Sum, ylab = "Sum serum lipids [nmol/ml]", xlab = "SampleID")
ggqqplot(LI_serum$PE, ylab = "Phosphatidylethanolamine
serum lipids [nmol/ml]", xlab = "SampleID")
Alle Probanden zeigen PRE und POST Proben, Follow-up nicht vorhanden
Loop für Wilcoxon-Test zwischend den Zeitpunkten PRE und POST
wilcox_LI<- data_frame()
for (i in LI_colnames) {
tmp <- LI_serum %>% drop_na(i)
x <- as.matrix(as.data.frame(lapply(tmp[,i], as.numeric)))
y <- LI_serum$Time
tmp_wilcox <- pairwise.wilcox.test(x, y, p.adjust.method = 'BH', paired = T)
p <- tmp_wilcox$p.value
nrow = nrow(wilcox_LI)+1
wilcox_LI[nrow, "LI"] <- i
wilcox_LI[nrow, "Mean PRE"] <-round(mean(subset(filter(LI_serum,Time == "PRE")[,i],!is.na(i),na.rm = TRUE), 2, mean, na.rm = TRUE), 4)
wilcox_LI[nrow, "sd PRE"] <-round(sd(c(subset(filter(LI_serum,Time == "PRE")[,i],!is.na(i),na.rm = TRUE), na.rm = TRUE)), 4)
wilcox_LI[nrow, "Mean POST"] <-round(mean(subset(filter(LI_serum,Time == "POST")[,i],!is.na(i), na.rm = TRUE), 2, mean, na.rm = TRUE), 4)
wilcox_LI[nrow, "sd POST"] <- round(sd(c(subset(filter(LI_serum,Time == "POST")[,i],!is.na(i), na.rm = TRUE),na.rm = TRUE)), 4)
wilcox_LI[nrow, "p.value"] <- round(p, 4) }
write.table(wilcox_LI, file = '/Users/student05/Documents/serum lipids/Tabellen/LI.pre.post.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten der Serumlipide zu den Zeitpunkten PRE und POST In Arbeit, unterteilt in Gylcerophospholipide und Sphingolipide
LI_serum.melt2 <- melt(LI_serum, id.vars = 'Time', measure.vars = c('PC', 'PCO', 'PE', 'PI','PEP', 'LPC'))
LI_serum.melt2 <- dplyr::rename(LI_serum.melt2, LI=variable)
LI_serum.melt2 <- dplyr::rename(LI_serum.melt2, Concentration=value)
pdf("/Users/student05/Documents/fertige Plots/SL.KD.pdf",width=9, height=10)
ggplot(LI_serum.melt2,aes(x=Time, y=Concentration, fill= LI)) +
xlab ('Zeitpunkt') + ylab ('Konzentration [nmol/ml]') +
geom_boxplot(width = .7, lwd=0.6)+ theme_classic()+
scale_fill_manual(labels = c("Phosphatidylcholine", "PCO", "Phosphatidylethanolamine", "Phosphatidylinositol", "PE based plasmalogens", "Lysophosphatidylcholine"),
values = c("#980043", "#dd1c77", "#df65b0", "#c994c7", "#d4b9da", "#f1eef6")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c( "POST")))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),axis.text=element_text(size=16))+
theme(legend.position="top")
dev.off()
LI_serum.melt1 <- melt(LI_serum, id.vars = 'Time', measure.vars = c('SM','CER'))
LI_serum.melt1 <- dplyr::rename(LI_serum.melt1, LI=variable)
LI_serum.melt1 <- dplyr::rename(LI_serum.melt1, Concentration=value)
pdf("/Users/student05/Documents/fertige Plots/SL2.KD.pdf",width=8, height=10)
ggplot(LI_serum.melt1,aes(x=Time, y=Concentration, fill= LI)) +
xlab ('Zeitpunkt') + ylab ('Konzentration [nmol/ml]') +
geom_boxplot(width = .3, lwd=0.8)+ theme_classic()+
scale_fill_manual(labels = c("Sphingomyelin", "Ceramide"),
values = c("#fa9fb5", "#fde0dd")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c( "POST")))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),axis.text=element_text(size=16))+
theme(legend.position="top")+
expand_limits(y=c(0, 2300))
dev.off()
Alle Serumlipide zusammen, Prozentuale Verteilung
LI_serum.melt <- melt(LI_serum, id.vars = 'Time', measure.vars = c('PC', 'PCO','SM', 'PE', 'PI','PEP', 'LPC','CER'))
LI_serum.melt <- dplyr::rename(LI_serum.melt, LI=variable)
LI_serum.melt <- dplyr::rename(LI_serum.melt, Concentration=value)
pdf("/Users/student05/Documents/fertige Plots/Serumlipids.alltimes.pdf",width=9, height=10)
ggplot(LI_serum.melt,aes(x=LI, y=Concentration, fill= LI)) +
xlab ('Serumlipid') + ylab ('Konzentration [nmol/ml]') +
scale_x_discrete(labels=c("PC" = "Phosphatidylcholine", "PCO" = "Phosphatidylcholine Plasmogen", "SM" = "Sphingomyelin", "PE" = "Phosphatidylethanolamine", "PI" = "Phosphatidylinositol", "PEP" = "Phosphatidylethanolamin Plasmalogen", "LPC" = "Lysophosphatidylcholine", "CER" ="Ceramid"))+
geom_boxplot(width = .5, lwd=0.5) + theme_classic()+
scale_fill_manual(labels = c("Phosphatidylcholine", "Phosphatidylcholine plasmogen", "Sphingomyelin", "Phosphatidylethanolamine", "Phosphatidylinositol", "PE based plasmalogens", "Lysophosphatidylcholine", "Ceramide"),
values = c("#df65b0", "#df65b0", "#fa9fb5", "#df65b0", "#df65b0", "#df65b0", "#df65b0", "#fa9fb5")) +
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(angle=25, hjust=1))+
theme(legend.position="top")
dev.off()
LI_serum.sum.melt <- melt(LI_serum, id.vars = 'Time', measure.vars = c('Sum', 'Sum.Membrane','Sum.Storage', 'Sum.Lyso'))
LI_serum.sum.melt <- rename(LI_serum.sum.melt, LI=variable)
LI_serum.sum.melt <- rename(LI_serum.sum.melt, Concentration=value)
ggplot(LI_serum.sum.melt,aes(x=Time, y=Concentration, fill= LI)) +
xlab ('Time Point') + ylab ('Concentration [nmol/ml]') +
geom_boxplot() +
scale_fill_manual(labels = c("Summary total", "Summary Membrane", "Summary Storage", "Summary Lyso"),
values = c("tomato", "yellowgreen", "steelblue2", "orchid2")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI_serum.p.melt <- melt(LI_serum, id.vars = 'Time', measure.vars = c( 'P.Membrane','P.Storage', 'P.Lyso'))
LI_serum.p.melt <- rename(LI_serum.p.melt, LI=variable)
LI_serum.p.melt <- rename(LI_serum.p.melt, Concentration=value)
ggplot(LI_serum.p.melt,aes(x=Time, y=Concentration, fill= LI)) +
xlab ('Time Point') + ylab ('Concentration [nmol/ml]') +
geom_boxplot() +
scale_fill_manual(labels = c( "Percentage Membrane", "Percentage Storage", "Percentage Lyso"),
values = c("yellowgreen", "steelblue2", "orchid2")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
Plotten der einzelnen Serumlipide, linked by Proband
ggpaired(LI_serum, x='Time', y='Sum', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('Timepoint') + ylab('Concentration Summary serum lipids [nmol/ml]') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='PC', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('PC serum lipids [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='PCO', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('PCO serum lipids [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='SM', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('SM serum lipids [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='LPC', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('Timepoint') + ylab('LPC serum lipids Concentration [nmol/ml]') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='PI', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('PI serum lipids [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='PEP', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('PEP serum lipids [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='LPC', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('LPC serum lipids [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='CER', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('Timepoint') + ylab('CER serum lipids Concentration[nmol/ml]') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='CER', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('CER serum lipids [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")+
geom_point(aes(color=Time), alpha=0.5) +
geom_boxplot(outlier.size=4, outlier.colour='blue', alpha=0.5)
ggpaired(LI_serum, x='Time', y='HexCer', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('Timepoint') + ylab('HexCer serum lipids Concentration [nmol/ml]') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='Sum.Membrane', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('Membrane serum lipids [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='Sum.Storage', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('Storage serum lipids [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='Sum.Lyso', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('Lyso serum lipids [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='P.Membrane', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('Membrane serum lipids [%]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='LPC.PC', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('LPC/PC serum lipid ratio') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='CER.SM', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('Cer/SM serum lipid ratio') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='HexCer.CER', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('HexCer/Cer serum lipid ratio') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
ggpaired(LI_serum, x='Time', y='PC.PE', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('PC/PE serum lipid ratio') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
Korrelationen zwischen einzelnen Serumlipiden, linked by Probands
LI_serum.melt1 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('PC', 'LPC'))
LI_serum.melt1 <- dplyr::rename(LI_serum.melt1, LI=variable)
LI_serum.melt1 <- dplyr::rename(LI_serum.melt1, Concentration=value)
LI_serum.melt1$Time <- factor(LI_serum.melt1$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt1, x='LI', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE) +
xlab('PC and LPC concentration [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)
LI_serum.melt2 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('Sum.Storage', 'Sum.Membrane'))
LI_serum.melt2 <- dplyr::rename(LI_serum.melt2, LI=variable)
LI_serum.melt2 <- dplyr::rename(LI_serum.melt2, Concentration=value)
LI_serum.melt2$Time <- factor(LI_serum.melt2$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt2, x='LI', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE) +
xlab('PC and LPC concentration [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)
LI_serum.melt2 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('Sum.Membrane', 'Sum.Lyso'))
LI_serum.melt2 <- rename(LI_serum.melt2, LI=variable)
LI_serum.melt2 <- rename(LI_serum.melt2, Concentration=value)
LI_serum.melt2$Time <- factor(LI_serum.melt2$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt2, x='LI', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE) +
xlab('PC and LPC concentration [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)
LI_serum.melt3 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('CER.SM', 'HexCer.CER'))
LI_serum.melt3<- rename(LI_serum.melt3, LI=variable)
LI_serum.melt3 <- rename(LI_serum.melt3, Concentration=value)
LI_serum.melt3$Time <- factor(LI_serum.melt2$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt3, x='LI', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE) +
xlab('PC and LPC concentration [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ Time, scales="free")
LI_serum.melt4 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('CER.SM', 'LPC'))
LI_serum.melt4<- rename(LI_serum.melt4, LI=variable)
LI_serum.melt4 <- rename(LI_serum.melt4, Concentration=value)
LI_serum.melt4$Time <- factor(LI_serum.melt4$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt4, x='LI', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE) +
xlab('PC and LPC concentration [nmol/ml]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ Time, scales="free")
LI_serum.melt5 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('PC.PE'))
LI_serum.melt5<- dplyr::rename(LI_serum.melt5, LI=variable)
LI_serum.melt5 <- dplyr::rename(LI_serum.melt5, Concentration=value)
LI_serum.melt5$Time <- factor(LI_serum.melt5$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt5, x='Time', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'LI', short.panel.labs = FALSE) +
xlab('Timepoint') + ylab('PC/PE ratio') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ LI, scales="free")+
theme(legend.position="none")
LI_serum.melt6 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('P.Storage', 'HexCer'))
LI_serum.melt6<- rename(LI_serum.melt6, LI=variable)
LI_serum.melt6 <- rename(LI_serum.melt6, Concentration=value)
LI_serum.melt6$Time <- factor(LI_serum.melt6$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt6, x='LI', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE) +
xlab('Storage and Membrane concentration [%]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ Time, scales="free")+
theme(legend.position="none")
LI_serum.melt6 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('LPC', 'PE'))
LI_serum.melt6<- rename(LI_serum.melt6, LI=variable)
LI_serum.melt6 <- rename(LI_serum.melt6, Concentration=value)
LI_serum.melt6$Time <- factor(LI_serum.melt6$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt6, x='LI', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE) +
xlab('Storage and Membrane concentration [%]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ Time, scales="free")+
theme(legend.position="none")
LI_serum.1 <- read.table("/Users/student05/Documents/serum lipids/serum lipids zahlen.1.2.txt", sep = '\t', comment='',head=T)
LI_serum.melt6 <- melt(LI_serum.1, id.vars = c('Proband'), measure.vars = c('Sum', 'PE'))
LI_serum.melt6<- rename(LI_serum.melt6, LI=variable)
LI_serum.melt6 <- rename(LI_serum.melt6, Concentration=value)
LI_serum.melt6$Time <- factor(LI_serum.melt6$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt6, x='LI', y='Concentration', color = 'black', fill = 'LI', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', short.panel.labs = FALSE) +
xlab('Storage and Membrane concentration [%]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
theme(legend.position="none")
Korrelationen zwischen den Serumlipiden, von welchen auch die Verhältnisse betrachtet wurden
LI_serum.melt6 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('LPC', 'PE'))
LI_serum.melt6<- rename(LI_serum.melt6, LI=variable)
LI_serum.melt6 <- rename(LI_serum.melt6, Concentration=value)
LI_serum.melt6$Time <- factor(LI_serum.melt6$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt6, x='LI', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE) +
xlab('Storage and Membrane concentration [%]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ Time, scales="free")+
theme(legend.position="none")
LI_serum.melt7 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('SM', 'CER'))
LI_serum.melt7<- dplyr::rename(LI_serum.melt7, LI=variable)
LI_serum.melt7 <- dplyr::rename(LI_serum.melt7, Concentration=value)
LI_serum.melt7$Time <- factor(LI_serum.melt7$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt7, x='LI', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE) +
xlab('Storage and Membrane concentration [%]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ Time, scales="free")+
theme(legend.position="none")
LI_serum.melt8 <- melt(LI_serum, id.vars = c('Time', 'Proband'), measure.vars = c('CER.SM'))
LI_serum.melt8 <- dplyr::rename(LI_serum.melt8, LI=variable)
LI_serum.melt8 <- dplyr::rename(LI_serum.melt8, Concentration=value)
ggplot(LI_serum.melt8,aes(x=Time, y=Concentration, fill= LI)) +
xlab ('Time Point') + ylab ('Concentration [nmol/ml]') +
geom_boxplot() +
scale_fill_manual(labels = c("CER/SM ratio"),
values = c("tomato")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
ggpaired(LI_serum.melt8, x='Time', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'LI', short.panel.labs = FALSE) +
xlab('Timepoint') + ylab('CER/SM ratio') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ LI, scales="free")+
theme(legend.position="none")
LI_serum.melt9 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('LPC', 'PC'))
LI_serum.melt9<- dplyr::rename(LI_serum.melt9, LI=variable)
LI_serum.melt9 <- dplyr::rename(LI_serum.melt9, Concentration=value)
LI_serum.melt9$Time <- factor(LI_serum.melt9$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt9, x='LI', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE) +
xlab('Storage and Membrane concentration [%]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ Time, scales="free")+
theme(legend.position="none")
LI_serum.melt11 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('PC', 'PE'))
LI_serum.melt11<- dplyr::rename(LI_serum.melt11, LI=variable)
LI_serum.melt11 <- dplyr::rename(LI_serum.melt11, Concentration=value)
LI_serum.melt11$Time <- factor(LI_serum.melt11$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt11, x='LI', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'Time', short.panel.labs = FALSE) +
xlab('Storage and Membrane concentration [%]') + ylab('Concentration') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ Time, scales="free")+
theme(legend.position="none")
pdf("/Users/student05/Documents/fertige Plots/PC.PE.Korr2.pdf",width=8, height=10)
ggscatter(LI_serum, x='PC', y='PE', add = 'reg.line', cor.coef.coord = c(950, 80), cor.coef.size = 8,conf.int = TRUE,
cor.coef = TRUE,color = "grey59",fill = "lightgray", cor.method = 'spearman', xlab= 'Phosphatidylcholinkonzentrationen [nmol/ml]', ylab = 'Phosphatidylethanolaminkonzentrationen [nmol/ml]')+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text( hjust=1))+
geom_point(color='grey52')+
theme(legend.position="none")+
geom_point(color='black', size=2.5)
dev.off()
cor.test(subset(filter(LI_serum))$PE, subset(filter(LI_serum))$PC, method = "spearman", exact = F)
cor.test(subset(filter(LI_serum))$PE, subset(filter(LI_serum))$PCO, method = "spearman", exact = F)
cor.test(subset(filter(LI_serum))$PE, subset(filter(LI_serum))$SM, method = "spearman", exact = F)
cor.test(subset(filter(LI_serum))$PE, subset(filter(LI_serum))$PI, method = "spearman", exact = F)
cor.test(subset(filter(LI_serum))$PE, subset(filter(LI_serum))$PEP, method = "spearman", exact = F)
cor.test(subset(filter(LI_serum))$PE, subset(filter(LI_serum))$LPC, method = "spearman", exact = F)
cor.test(subset(filter(LI_serum))$PE, subset(filter(LI_serum))$CER, method = "spearman", exact = F)
p.adjust(c(0.7706423 ,0.0001885,3.964e-07, 5.833e-16, 0.3947, 0.3421,0.007615 ), method = 'BH', n=7)
Plotten der Serumlipid-Verhältnisse
LI_serum.melt10 <- melt(LI_serum, id.vars = c('Time', 'Proband'), measure.vars = c('LPC.PC'))
LI_serum.melt10 <- dplyr::rename(LI_serum.melt10, LI=variable)
LI_serum.melt10 <- dplyr::rename(LI_serum.melt10, Concentration=value)
ggplot(LI_serum.melt10,aes(x=Time, y=Concentration, fill= LI)) +
xlab ('Time Point') + ylab ('Concentration [nmol/ml]') +
geom_boxplot() +
scale_fill_manual(labels = c("LPC/PC ratio"),
values = c("steelblue")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
ggpaired(LI_serum.melt10, x='Time', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'LI', short.panel.labs = FALSE) +
xlab('Timepoint') + ylab('LPC/PC ratio') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ LI, scales="free")+
theme(legend.position="none")
LI_serum.melt12 <- melt(LI_serum, id.vars = 'Time', measure.vars = c('PC.PE'))
LI_serum.melt12 <- dplyr::rename(LI_serum.melt12, LI=variable)
LI_serum.melt12 <- dplyr::rename(LI_serum.melt12, Concentration=value)
ggplot(LI_serum.melt12,aes(x=Time, y=Concentration, fill= LI)) +
xlab ('Time Point') + ylab ('Concentration [nmol/ml]') +
geom_boxplot() +
scale_fill_manual(labels = c("PC/PE ratio"),
values = c("darkgreen")) +
stat_compare_means(method = "wilcox.test", paired = TRUE, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI_serum.melt5 <- melt(LI_serum, id.vars = c('Time','Proband'), measure.vars = c('PC.PE'))
LI_serum.melt5<- dplyr::rename(LI_serum.melt5, LI=variable)
LI_serum.melt5 <- dplyr::rename(LI_serum.melt5, Concentration=value)
LI_serum.melt5$Time <- factor(LI_serum.melt5$Time, levels = c("PRE", "POST"))
ggpaired(LI_serum.melt5, x='Time', y='Concentration', color = 'black', fill = 'Time', palette = c('whitesmoke','whitesmoke'), line.color = 'grey60', line.size = 0.4, group = 'Proband', facet.by = 'LI', short.panel.labs = FALSE) +
xlab('Timepoint') + ylab('PC/PE ratio') +
geom_text(aes(label=Proband),hjust=0, vjust=0)+
facet_grid(.~ LI, scales="free")+
theme(legend.position="none")
6.2 Korrelationsanalysen zwischen Ceramid und Omega6-FA
Laden und filtern der Metadaten
LI_CER6 <- read.table("/Users/student05/Documents/omegga6:cer.txt", sep = '\t', comment='',head=T)
LI_CER6$Time <- factor(LI_CER6$Time, levels =c("PRE", "POST"))
LI_CER6 <- subset(filter(LI_CER6, !Proband == "33MP"))
Plotten der Korrelationen
In Arbeit
pdf("/Users/student05/Documents/fertige Plots/Ceramid.Linolsäure.pdf",width=8.5, height=10)
ggscatter(LI_CER6, x='CER', y='Linolsaeure_mol',color = 'Time',size = 2.5, palette = c('skyblue', 'orchid'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(8, 1000), cor.coef.size = 8, xlab= 'Ceramid Konzentrationen [nmol/ml]', ylab = 'Fäkale Linolsäurekonzentrationen [nmol/g]')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
dev.off()
ggscatter(LI_CER6, x='CER', y='Linolsaeure_mol', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'serum ceramide concentration [nmol/ml]', ylab = 'fecal linoleic fatty acid concentration [nmol/g]')+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(LI_CER6, x='CER', y='Linolsaeure_i',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'serum CER concentration [nmol/ml]', ylab = 'fecal linoleic fatty acid concentration [nmol/g]')+
facet_grid(.~ Time)+
theme(strip.text.x = element_text(size = 8, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
6.3 Erstellen einer Korrelationsmatrix zum testen von Korrelationen zwischen den Serumlipiden
Filtern für PRE und POST
LI_serum_matrix_PRE <- subset(filter(LI_serum, Time == "PRE"))[ ,7:26]
LI_serum_matrix_POST <- subset(filter(LI_serum, Time == "POST"))[ ,7:26]
res.PRE <- cor(LI_serum_matrix_PRE)
res.POST <- cor(LI_serum_matrix_POST)
Spearman-Rangkorrelation und hinzufügen von Korrelationkoeffizient und p-value
res2.PRE <- rcorr(as.matrix(LI_serum_matrix_PRE), type = "spearman")
res2.POST <- rcorr(as.matrix(LI_serum_matrix_POST), type = "spearman")
res2.PRE$r
res2.POST$r
LI_serum_PRE_CC <- as.matrix((res2.PRE$r))
LI_serum_POST_CC <- as.matrix(res2.POST$r)
res2$P
LI_serum_PRE_PV <- as.matrix(res2.PRE$P)
LI_serum_POST_PV <- as.matrix(res2.POST$P)
Erstellen einer flattenCorrMatrix für PRE und POST
flattenCorrMatrix.PRE <- function(LI_serum_PRE_CC, LI_serum_PRE_PV) {
ut <- upper.tri(LI_serum_PRE_CC)
data.frame(
row = rownames(LI_serum_PRE_CC)[row(LI_serum_PRE_CC)[ut]],
column = rownames(LI_serum_PRE_CC)[col(LI_serum_PRE_CC)[ut]],
cor =(LI_serum_PRE_CC)[ut],
p = LI_serum_PRE_PV[ut]
)
}
flattenCorrMatrix.PRE(res2.PRE$r, res2.PRE$P)
flattenCorrMatrix.POST <- function(LI_serum_POST_CC, LI_serum_POST_PV) {
ut <- upper.tri(LI_serum_POST_CC)
data.frame(
row = rownames(LI_serum_POST_CC)[row(LI_serum_POST_CC)[ut]],
column = rownames(LI_serum_POST_CC)[col(LI_serum_POST_CC)[ut]],
cor =(LI_serum_POST_CC)[ut],
p = LI_serum_POST_PV[ut]
)
}
flattenCorrMatrix.POST(res2.POST$r, res2.POST$P)
Dataframe erstellen
LI_PRE_cor.p <- as.data.frame(flattenCorrMatrix.PRE(res2.PRE$r, res2.PRE$P))
LI_POST_cor.p <- as.data.frame(flattenCorrMatrix.POST(res2.POST$r, res2.POST$P))
colnames(LI_PRE_cor.p) <- c("LI", "LI", "correlation coefficient", "p-value")
colnames(LI_POST_cor.p) <- c("LI", "LI", "correlation coefficient", "p-value")
Corrplot erstellen zu den Zeiten PRE und POST
corrplot(res.PRE, type = "upper", order = "hclust",
tl.col = "black", tl.srt = 45)
corrplot(res.POST, type = "upper", order = "hclust",
tl.col = "black", tl.srt = 45)
corrplot(res2.PRE$r, type="upper", order="hclust",
p.mat = res2.PRE$P, sig.level = 0.05, insig = "blank")
corrplot(res2.PRE$r, type="upper", order="hclust",
p.mat = res2.PRE$P, sig.level = 0.05, insig = "blank")
Scatterplots erstellen zu den Zeiten PRE und POST
chart.Correlation(LI_serum_matrix_PRE, histogram=TRUE, pch=19)
chart.Correlation(SCFA_stool_matrix_POST, histogram = T, pch = 19)
6.4 Unterschiede der Serumlipidkonzentrationen zwischen Sterolkonvertierungstypen
Laden und filtern der Daten Lipidmetadaten s.o. In high und low converter unterteilen
lowconv <- filter(LI_serum, Proband == "05AP" | Proband == "33MP"
| Proband == "38AR" | Proband == "40WA" | Proband == "41ML"
| Proband == "47OT" | Proband == "49RJ" | Proband == "50DM")
lowconv['Phenotype'] = 'low converter'
highconv <- filter(LI_serum, Proband == "06WT" | Proband == "07RW"
| Proband == "13BS" | Proband == "17SK" | Proband == "22WS"
| Proband == "25FE" | Proband == "26FB" | Proband == "29MK"
| Proband == "30HB" | Proband == "31KE" | Proband == "36ER"
| Proband == "45GL" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
highconv['Phenotype'] = 'high converter'
highconv$Converter.Type <- NULL
lowconv$Converter.Type <- NULL
noconv <- filter(LI_serum, Proband == "28HM" | Proband == "32FG"
| Proband == "34WF" | Proband == "35AD" | Proband == "37SD"
| Proband == "39DA" | Proband == "66DG" | Proband == "70PL")
noconv['Phenotype'] = 'not classified'
noconv$Converter.Type <- NULL
convT <- data.frame()
convT <- bind_rows(lowconv, highconv, noconv)
convT_paired <- filter(convT, Proband == "05AP" | Proband == "06WT"
| Proband == "07RW" | Proband == "13BS" | Proband == "17SK"
| Proband == "22WS" | Proband == "25FE" | Proband == "26FB"
| Proband == "28HM" | Proband == "29MK" | Proband == "30HB"
| Proband == "31KE" | Proband == "32FG" | Proband == "36ER"
| Proband == "37SD" | Proband == "38AR" | Proband == "40WA"
| Proband == "41ML" | Proband == "45GL" | Proband == "47OT"
| Proband == "50DM" | Proband == "53BD" | Proband == "54SL"
| Proband == "57MT" | Proband == "69HL" | Proband == "74SA")
Plotten der Unterschiede der Serumlipidkonzentrationen zwischen den Sterolkonvertierungstypen
LI_serum.melt <- melt(convT_paired, id.vars = c('Phenotype', 'Time'), measure.vars = c('PC', 'PCO', 'SM', 'PE', 'PI','PEP', 'LPC', 'CER', 'HexCer'))
LI_serum.melt <- subset(filter(LI_serum.melt, !Phenotype == "not classified"))
LI_serum.melt <- rename(LI_serum.melt, variable=LI)
LI_serum.melt <- rename(LI_serum.melt, Concentration=value)
ggplot(LI_serum.melt,aes(x=Phenotype, y=value, fill= variable)) +
xlab ('Converter type') + ylab ('Concentration [nmol/ml]') +
geom_boxplot()+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
facet_grid(.~Time)+
theme(legend.position="top")
LI_serum.melt1 <- melt(convT_paired, id.vars = c('Phenotype', 'Time'), measure.vars = c('Sum', 'Sum.Membrane','Sum.Storage', 'Sum.Lyso'))
LI_serum.melt1 <- subset(filter(LI_serum.melt1, !Phenotype == "not classified"))
LI_serum.melt1 <- rename(LI_serum.melt1, variable=LI)
LI_serum.melt1 <- rename(LI_serum.melt1, Concentration=value)
ggplot(LI_serum.melt1,aes(x=Phenotype, y=value, fill= variable)) +
xlab ('Converter type') + ylab ('Concentration [nmol/ml]') +
geom_boxplot()+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
facet_grid(.~Time)+
theme(legend.position="top")+
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))
Plotten der Unterschiede der Serumlipidverhältnisse zwischen den Sterolkonvertierungstypen
LI.r1 <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('LPC.PC'))
ggplot(filter(LI.r1, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("LPC/PC"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.Sum.m, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("sum membrane"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI.r2 <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('CER.SM'))
ggplot(filter(LI.r2, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("CER/SM"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.Sum.m, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("sum membrane"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI_serum.melt2 <- melt(convT_paired, id.vars = c('Phenotype', 'Time'), measure.vars = c( 'PC.PE'))
LI_serum.melt2 <- subset(filter(LI_serum.melt2, !Phenotype == "not classified"))
LI_serum.melt2 <- dplyr::rename(LI_serum.melt2, variable= LI)
LI_serum.melt2 <- dplyr::rename(LI_serum.melt2, Concentration=value)
comparison_conv <- list(c("low converter", "high converter"))
comparison_time <- list(c("PRE", "POST"))
ggplot(LI_serum.melt2,aes(x=Phenotype, y=value, fill= variable)) +
xlab ('Converter type') + ylab ('PC/PE ratio') +
geom_boxplot()+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=45, hjust=1))+
facet_grid(.~Time)+
theme(legend.position="none")+
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))
ggplot(LI_serum.melt2,aes(x=Time, y=value, fill= variable)) +
xlab ('Converter type') + ylab ('PC/PE ratio') +
geom_boxplot()+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=0, hjust=1))+
facet_grid(.~Phenotype)+
theme(legend.position="none")+
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))
Wilcoxon-Test, mean und SD, Plotten der Unterschiede des PC/PE-Verhältnisses zwischen den Sterolkonvertierungstypen In Arbeit
mean(subset(filter(convT_paired, Time == "PRE" & Phenotype == "high converter"))$PC.PE)
sd(subset(filter(convT_paired, Time == "PRE" & Phenotype == "high converter"))$PC.PE)
mean(subset(filter(convT_paired, Time == "POST" & Phenotype == "high converter"))$PC.PE)
sd(subset(filter(convT_paired, Time == "POST" & Phenotype == "high converter"))$PC.PE)
mean(subset(filter(convT_paired, Time == "PRE" & Phenotype == "low converter"))$PC.PE)
sd(subset(filter(convT_paired, Time == "PRE" & Phenotype == "low converter"))$PC.PE)
mean(subset(filter(convT_paired, Time == "POST" & Phenotype == "low converter"))$PC.PE)
sd(subset(filter(convT_paired, Time == "POST" & Phenotype == "low converter"))$PC.PE)
pairwise.wilcox.test(subset(filter(convT_paired, Time == "PRE"))$PC.PE, subset(filter(convT_paired, Time == "PRE"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(convT_paired, Time == "POST"))$PC.PE, subset(filter(convT_paired, Time == "POST"))$Phenotype, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(convT_paired, Phenotype == "low converter"))$PC.PE, subset(filter(convT_paired, Phenotype == "low converter"))$Time, p.adjust.method = 'BH', paired = F)
pairwise.wilcox.test(subset(filter(convT_paired, Phenotype == "high converter"))$PC.PE, subset(filter(convT_paired, Phenotype == "high converter"))$Time, p.adjust.method = 'BH', paired = F)
LI.r2 <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('PC.PE'))
LI.r2 <- rename( LI.r2, LI=variable)
LI.r2 <- rename( LI.r2, Concentration=value)
pdf("/Users/student05/Documents/fertige Plots/converter.PC.PE.pdf",width=8, height=10)
ggplot(filter(LI.r2, !Phenotype=="not classified"),aes(x=Phenotype, y=Concentration, fill= Phenotype)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Phosphatidylcholin/Phosphatidylethanolamin Verhältnis') +
scale_fill_manual(labels=c("high converter", "low converter"), values = c("seashell4", "seashell2"))+
geom_boxplot(width = .7, lwd=0.6) + theme_classic() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("low converter")))+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18, colour = "black"),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
dev.off()
ggplot(filter(LI.r2, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("PC/PE"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.Sum.m, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("sum membrane"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
Plotten der Unterschiede einzelner Serumlipidkonzentrationen zwischen den Sterolkonvertierungstypen
LI.PCO <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('PCO'))
LI.PCO <- rename(LI.PCO, FA=variable)
LI.PCO <- rename(LI.PCO, Concentration=value)
ggplot(filter(LI.PCO, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("PCO"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.PCO, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("PCO"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI.SM <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('SM'))
LI.SM <- rename(LI.SM, FA=variable)
LI.SM <- rename(LI.SM, Concentration=value)
ggplot(filter(LI.SM, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("SM"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.SM, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("SM"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI.PE <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('PE'))
LI.PE <- rename(LI.PE, FA=variable)
LI.PE <- rename(LI.PE, Concentration=value)
ggplot(filter(LI.PE, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("PE"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.SM, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("SM"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI.PI <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('PI'))
LI.PI <- rename(LI.PI, FA=variable)
LI.PI <- rename(LI.PI, Concentration=value)
ggplot(filter(LI.PI, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("PI"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.PI, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("PI"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI.PEP <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('PEP'))
LI.PEP <- rename(LI.PEP, FA=variable)
LI.PEP <- rename(LI.PEP, Concentration=value)
ggplot(filter(LI.PEP, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("PEP"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.PEP, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("PEP"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI.LPC <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('LPC'))
LI.LPC <- rename(LI.LPC, FA=variable)
LI.LPC <- rename(LI.LPC, Concentration=value)
ggplot(filter(LI.LPC, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("LPC"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.LPC, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("LPC"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI.CER <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('CER'))
ggplot(filter(LI.CER, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("CER"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.LPC, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("LPC"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI.HexCer <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('HexCer'))
ggplot(filter(LI.HexCer, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("HEXCER"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.HexCer, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("HexCer"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI.Sum <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('Sum'))
ggplot(filter(LI.Sum, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("SUM"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.HexCer, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("HexCer"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI.Sum.m <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('Sum.Membrane'))
ggplot(filter(LI.Sum.m, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("SUM Membrane"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.Sum.m, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("sum membrane"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI.Sum.s <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('Sum.Storage'))
ggplot(filter(LI.Sum.s, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("SUM Storage"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.Sum.m, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("sum membrane"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
LI.Sum.l <- melt(convT_paired, id.vars = c('Phenotype','Time'), measure.vars = c('Sum.Lyso'))
ggplot(filter(LI.Sum.l, !Phenotype=="not classified"),aes(x=Phenotype, y=value, fill= variable)) +
facet_grid(.~ Time) +
xlab ('Converter type')+ ylab ('Concentration [nmol/ml] ') +
scale_fill_manual(labels=c("SUM Lyso"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = F, aes(labels = ..p.signif..), comparisons =list(c("high converter", "low converter")))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="top")
ggplot(filter(LI.Sum.m, !Phenotype=="not classified"),aes(x=Time, y=value, fill= variable)) +
facet_grid(.~ Phenotype) +
xlab ('Time Point')+ ylab ('Concentration [nmol/ml]') +
scale_fill_manual(labels=c("sum membrane"), values = c("steelblue2"))+
geom_boxplot() +
stat_compare_means(method = "wilcox.test", paired = T, aes(labels = ..p.signif..), comparisons =list(c("PRE", "POST")))+
theme(legend.position="top")
6.4 alpha-Diversitätsanalysen mit Serumlipide
Laden, filtern und synchronisieren der Metadaten
map_alphadiv <- read.table("/Users/student05/Downloads/means_alpha_div.txt", sep = '\t', comment='',head = TRUE, row.names = 1)
LI_serum <- read.table("/Users/student05/Documents/serum lipids zahlen.1-2.txt", sep = '\t', comment='',head=T)
LI_serum$Time <-factor(LI_serum$Time, levels = c("PRE", "POST"))
row.names(LI_serum) <- LI_serum$SampleID
row.names(map_alphadiv)
common.ids.St <- intersect(rownames(LI_serum), rownames(map_alphadiv))
common.ids.St <- intersect(row.names(LI_serum), row.names(map_alphadiv))
LI_serum <- LI_serum[common.ids.St,]
map_alphadiv <- map_alphadiv[common.ids.St,]
LI_serum$Shannon <- map_alphadiv$Shannon
LI_serum$Simpson <- map_alphadiv$Simpson
Loop für Korrelationsanalyse zwischen Shannon-Index und Serumlipiden
corr_colnames_LI <-colnames(LI_serum[,7:26])
corr_spearman_Shannon_LI <- data.frame()
for( i in unique(corr_colnames_LI)) {
tmp <- filter(LI_serum, !is.na(i))
x = as.matrix(as.data.frame(lapply(tmp[,i], as.numeric)))
y = t(as.matrix(tmp$Shannon) )
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "PRE"))[,i],as.numeric)))
w = t(as.matrix(subset(filter(tmp, Time == "PRE"))$Shannon))
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "POST"))[,i],as.numeric)))
s = t(as.matrix(subset(filter(tmp, Time == "POST"))$Shannon))
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Shannon_LI)+1
corr_spearman_Shannon_LI[nrow,"Div"] = "Shannon"
corr_spearman_Shannon_LI[nrow, "column"] = i
corr_spearman_Shannon_LI[nrow, "rho"] = rho
corr_spearman_Shannon_LI[nrow, "p.value"] = p
corr_spearman_Shannon_LI[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Shannon_LI[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Shannon_LI[nrow, "rho_POST"] = rho_POST
corr_spearman_Shannon_LI[nrow, "p.value_POST"] = p_POST
}
corr_spearman_Shannon_LI$p.adjusted <- p.adjust(corr_spearman_Shannon_LI$p.value,method = "BH", n = 20)
corr_spearman_Shannon_LI$p.adjusted_PRE <-p.adjust(corr_spearman_Shannon_LI$p.value_PRE, method = "BH", n = 20)
corr_spearman_Shannon_LI$p.adjusted_POST <- p.adjust(corr_spearman_Shannon_LI$p.value_POST, method = "BH", n = 20)
corr_spearman_Shannon_LI$p.adjusted_FU <- p.adjust(corr_spearman_Shannon_LI$p.value_FU, method = "BH", n = 20)
write.table(corr_spearman_Shannon_LI, file = '/Users/student05/Documents/serum lipids/diversity/LI.Shannon.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
Plotten von Korrelationen zwischen Shannon-Index und Serumlipiden
alle Lipide
LI_serum.melt <- melt(LI_serum, id.vars = c('Time','Shannon'), measure.vars = c( 'PC', 'PCO', 'SM', 'PE', 'PI','PEP', 'LPC', 'CER', 'HexCer'))
LI_serum.melt <- dplyr::rename(LI_serum.melt, LI=variable)
LI_serum.melt <- dplyr::rename(LI_serum.melt, Concentration=value)
LI_serum.melt.pr <- subset(filter(LI_serum.melt, !Time =='POST'))
LI_serum.melt.po <- subset(filter(LI_serum.melt, !Time =='PRE'))
ggscatter(LI_serum.melt.pr, x='Concentration', y='Shannon',color = 'LI', palette = c('tomato', 'yellowgreen', 'steelblue2', 'orchid2', 'deeppink', 'brown4', 'darkorange1', 'blueviolet', 'aquamarine3'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c( 100, 7), xlab= 'serum lipid Concentration [nmol/ml]', ylab = 'Shannon-Index')+
facet_grid(.~ LI,scales = "free_x")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(LI_serum.melt, x='Concentration', y='Shannon',color = 'LI', palette = c('tomato', 'yellowgreen', 'steelblue2', 'orchid2', 'deeppink', 'brown4', 'darkorange1', 'blueviolet', 'aquamarine3'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'serum lipid Concentration [nmol/ml]', ylab = 'Shannon-Index')+
facet_grid(.~ LI,scales = "free_x")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(LI_serum.melt.po, x='Concentration', y='Shannon',color = 'LI', palette = c('tomato', 'yellowgreen', 'steelblue2', 'orchid2', 'deeppink', 'brown4', 'darkorange1', 'blueviolet', 'aquamarine3'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE,cor.coef.coord = c(NULL, NULL),
cor.method = 'spearman', xlab= 'serum lipid Concentration [nmol/ml]', ylab = 'Shannon-Index')+
facet_grid(.~ LI,scales = "free_x")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Summierten Lipidkonzentrationen
LI_serum.melt1 <- melt(LI_serum, id.vars = c('Time','Shannon'), measure.vars = c( 'Sum', 'Sum.Membrane','Sum.Storage', 'Sum.Lyso'))
LI_serum.melt1 <- dplyr::rename(LI_serum.melt1, LI=variable)
LI_serum.melt1<- dplyr::rename(LI_serum.melt1, Concentration=value)
LI_serum.melt1.pr <- subset(filter(LI_serum.melt1, !Time =='POST'))
LI_serum.melt1.po <- subset(filter(LI_serum.melt1, !Time =='PRE'))
ggscatter(LI_serum.melt1.pr, x='Concentration', y='Shannon',color = 'LI', palette = c('tomato', 'yellowgreen', 'steelblue2', 'orchid2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0, 7), xlab= 'sum serum lipid Concentration [nmol/ml]', ylab = 'Shannon-Index')+
facet_grid(.~ LI,scales = "free_x")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(LI_serum.melt1.po, x='Concentration', y='Shannon',color = 'LI', palette = c('tomato', 'yellowgreen', 'steelblue2', 'orchid2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'serum lipid Concentration [nmol/ml]', ylab = 'Shannon-Index')+
facet_grid(.~ LI,scales = "free_x")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Lipidverhältnisse
LI_serum.melt2 <- melt(LI_serum, id.vars = c('Time','Shannon'), measure.vars = c( 'LPC.PC','CER.SM', 'PC.PE'))
LI_serum.melt2 <- dplyr::rename(LI_serum.melt2, LI=variable)
LI_serum.melt2<- dplyr::rename(LI_serum.melt2, Concentration=value)
LI_serum.melt2.pr <- subset(filter(LI_serum.melt2, !Time =='POST'))
LI_serum.melt2.po <- subset(filter(LI_serum.melt2, !Time =='PRE'))
ggscatter(LI_serum.melt2.pr, x='Concentration', y='Shannon',color = 'LI', palette = c('tomato', 'yellowgreen', 'steelblue2', 'orchid2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0.03, 7), xlab= 'ratio serum lipids', ylab = 'Shannon-Index')+
facet_grid(.~ LI,scales = "free_x")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(LI_serum.melt2.po, x='Concentration', y='Shannon',color = 'LI', palette = c('tomato', 'yellowgreen', 'steelblue2', 'orchid2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0.03, 7), xlab= 'ratio serum lipids', ylab = 'Shannon-Index')+
facet_grid(.~ LI,scales = "free_x")+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(LI_serum, x='PC.PE', y='Shannon',color = 'Time', palette = c('tomato', 'yellowgreen', 'steelblue2', 'orchid2'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(40, 7),cor.coef.size = 6, xlab= 'PC/PE serum lipid ratio', ylab = 'Shannon-Index')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
ggscatter(LI_serum, x='PC.PE', y='Shannon', palette = c('tomato', 'yellowgreen', 'steelblue2', 'orchid2'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(40, 7),cor.coef.size = 6, xlab= 'PC/PE serum lipid ratio', ylab = 'Shannon-Index')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
Loop für Korrelationsanalyse zwischen Simpson-Index und Serumlipiden
corr_spearman_Simpson_LI <- data.frame()
for( i in unique(corr_colnames_LI)) {
tmp <- filter(LI_serum, !is.na(i))
x = as.matrix(as.data.frame(lapply(tmp[,i], as.numeric)))
y = t(as.matrix(tmp$Simpson))
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "PRE"))[,i],as.numeric)))
w = t(as.matrix (subset(filter(tmp, Time == "PRE"))$Simpson))
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = as.matrix(as.data.frame(lapply(subset(filter(tmp, Time == "POST"))[,i],as.numeric)))
s = t(as.matrix(subset(filter(tmp, Time == "POST"))$Simpson))
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Simpson_LI)+1
corr_spearman_Simpson_LI[nrow,"Div"] = "Simpson"
corr_spearman_Simpson_LI[nrow, "column"] = i
corr_spearman_Simpson_LI[nrow, "rho"] = rho
corr_spearman_Simpson_LI[nrow, "p.value"] = p
corr_spearman_Simpson_LI[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Simpson_LI[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Simpson_LI[nrow, "rho_POST"] = rho_POST
corr_spearman_Simpson_LI[nrow, "p.value_POST"] = p_POST
}
corr_spearman_Simpson_LI$p.adjusted <- p.adjust(corr_spearman_Simpson_LI$p.value,method = "BH", n = 20)
corr_spearman_Simpson_LI$p.adjusted_PRE <-p.adjust(corr_spearman_Simpson_LI$p.value_PRE, method = "BH", n = 20)
corr_spearman_Simpson_LI$p.adjusted_POST <- p.adjust(corr_spearman_Simpson_LI$p.value_POST, method = "BH", n = 20)
corr_spearman_Simpson_LI$p.adjusted_FU <- p.adjust(corr_spearman_Simpson_LI$p.value_FU, method = "BH", n = 20)
write.table(corr_spearman_Simpson_LI, file = '/Users/student05/Documents/serum lipids/diversity/LI.Simpson.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
-> gleicher Effekt wie bei Shannon-Index
6.5 Korrelationsanalysen zwischen dem relativen Vorkommen von Taxa und Serumlipiden
Laden und filtern der Metadaten
map_KD <- read.table("/Users/student05/Documents/txt dateien r/Mappingfile_16SrRNA_BC22.txt", sep ='\t', comment='', head=T,row.names = 1)
relab <- read.table("/Users/student05/Documents/relative abundance/L6_metadata_taxa_strict_stool.txt", sep = '\t', comment='', head=T)
relab_PRE <- filter(relab, Time == "PRE")
relab_POST <- filter(relab, Time == "POST")
relab_FU <- filter(relab, Time == "FOLLOW-UP")
relab_means_PRE <- aggregate(relab_PRE[, 10:90], list(relab_PRE$Proband), mean)
relab_means_PRE['Time'] = 'PRE'
relab_means_PRE <- dplyr::rename(relab_means_PRE, Proband=Group.1)
relab_means_POST <- aggregate(relab_POST[, 10:90], list(relab_POST$Proband), mean)
relab_means_POST['Time'] = 'POST'
relab_means_POST <- dplyr::rename(relab_means_POST, Proband=Group.1)
relab_means_FU <- aggregate(relab_FU[, 10:90], list(relab_FU$Proband), mean)
relab_means_FU['Time'] = 'FOLLOW-UP'
relab_means_FU <- dplyr::rename(relab_means_FU, Proband=Group.1)
relab_means <- data_frame()
relab_means <- bind_rows(relab_means_PRE, relab_means_POST, relab_means_FU)
relab_means <- relab_means[, c(1, 83, 2:82)]
relab_means_melt <- melt(relab_means, id=c('Proband', 'Time'))
relab_means_melt <- dplyr::rename(relab_means_melt, Taxa=variable)
relab_means_melt <- dplyr::rename(relab_means_melt, Relative_Abundance=value)
relab_phylum <- subset(relab_means_melt, !grepl("g__|f__|o__|c__", relab_means_melt$Taxa))
relab_phylum <- subset(relab_phylum, !grepl("k__Archaea", relab_phylum$Taxa))
relab_phylum$Time <- factor(relab_phylum$Time, levels=c('PRE','POST','FOLLOW-UP'))
relab_phylum_spread <- spread(relab_phylum, Taxa, Relative_Abundance, sep = NULL)
relab_genus <- subset(relab_means_melt, grepl("g__", relab_means_melt$Taxa))
relab_genus <- subset(relab_genus, !grepl("k__Archaea", relab_genus$Taxa))
relab_genus$Time <- factor(relab_genus$Time, levels = c('PRE','POST','FOLLOW-UP'))
relab_genus_spread <- spread(relab_genus, Taxa, Relative_Abundance, sep = NULL)
Laden der Serumlipidmetadaten, Synchonisieren der Metadaten
LI_serum <- read.table("/Users/student05/Documents/serum lipids zahlen.1-2.txt", sep = '\t', comment='',head=T)
LI_serum$Time <-factor(LI_serum$Time, levels = c("PRE", "POST"))
relab_phylum_ID <- relab_phylum_spread
relab_phylum_ID <- mutate(relab_phylum_ID, SampleID = paste(Proband, Time,sep="."))
row.names(relab_phylum_ID) <- relab_phylum_ID$SampleID
relab_genus_ID <- relab_genus_spread
relab_genus_ID <- mutate(relab_genus_ID, SampleID = paste(Proband, Time, sep ="."))
row.names(relab_genus_ID) <- relab_genus_ID$SampleID
LI_serum <- mutate(LI_serum, SampleID1 = paste(Proband, Time, sep = "."))
row.names(LI_serum) <- LI_serum$SampleID1
common.ids.relab <- intersect(rownames(LI_serum), rownames(relab_phylum_ID))
LI_serum <- LI_serum[common.ids.relab,]
relab_phylum_ID <- relab_phylum_ID[common.ids.relab,]
relab_genus_ID <- relab_genus_ID[common.ids.relab,]
Subsetten des Phylum-levels, log-Transformation und hinzufühen von Pseudocount 0.00001 Filtern nach Proben mit PRE und POST
phylum_colnames <- colnames(relab_phylum_spread[, c(3:8)])
relab_phylum_ID1 <- relab_phylum_ID[,c(3:8)] + 0.00001
relab_phylum_ID_log <- log10(relab_phylum_ID_log)
phylum_LI <- cbind(relab_phylum_ID1, LI_serum[, c(1:27)])
phylum_LI$Proband
phylum_LI <- subset(filter(phylum_LI, !Proband == '31KE'))
phylum_LI <- subset(filter(phylum_LI, !Proband == '45GL'))
phylum_LI <- subset(filter(phylum_LI, !Proband == '34WF'))
phylum_LI <- subset(filter(phylum_LI, !Proband == '54SL'))
phylum_LI <- subset(filter(phylum_LI, !Proband == '74SA'))
phylum_LI$Time <- factor(phylum_LI$Time, levels = c("PRE", "POST"))
Loop und Plots Korrelation zwischen Phosphatidylcholin und phylum-level
In Arbeit
corr_map_phylum_PC <- filter(phylum_LI, !is.na(PC))
corr_spearman_Phylum_PC <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_PC, !is.na(i))
y = tmp[,i]
x = tmp$PC
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$PC
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$PC
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_PC)+1
corr_spearman_Phylum_PC[nrow,"FA"] <- "PC"
corr_spearman_Phylum_PC[nrow, "Phylum"] = i
corr_spearman_Phylum_PC[nrow, "p.value"] = p
corr_spearman_Phylum_PC[nrow, "rho"] = rho
corr_spearman_Phylum_PC[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_PC[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_PC[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_PC[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_PC$p.adjusted <- p.adjust(corr_spearman_Phylum_PC$p.value, method = "BH", n = 35)
corr_spearman_Phylum_PC$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_PC$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_PC$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_PC$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_PC, file = '/Users/student05/Documents/serum lipids/phylum/PC.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='PC', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Phosphatidylcholinkonzentrationen [nmol/ml]', ylab = 'log10 (Relatives Vorkommen p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
pdf("/Users/student05/Documents/fertige Plots/PC.Proteo.pdf",width=8, height=10)
ggscatter(phylum_LI, x='PC', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('skyblue', 'orchid'),size = 2.5, add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(1000, -1.5), cor.coef.size = 8,xlab= 'Phosphatidylcholinkonzentrationen [nmol/ml]', ylab = 'Relatives Vorkommen p__Proteobacteria [%]')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(hjust=1))+
scale_y_log10(labels = percent_format())+
theme(legend.position="none")
dev.off()
ggscatter(phylum_LI, x='PC', y='k__Bacteria.p__Proteobacteria', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(1000, -1.5), cor.coef.size = 5,xlab= 'PC serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PC', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PC', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Phosphatidylcholin-Plasmalogen und phylum-level
corr_map_phylum_PCO <- filter(phylum_LI, !is.na(PCO))
corr_spearman_Phylum_PCO <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_PCO, !is.na(i))
y = tmp[,i]
x = tmp$PCO
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$PCO
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$PCO
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_PCO)+1
corr_spearman_Phylum_PCO[nrow,"FA"] <- "PCO"
corr_spearman_Phylum_PCO[nrow, "Phylum"] = i
corr_spearman_Phylum_PCO[nrow, "p.value"] = p
corr_spearman_Phylum_PCO[nrow, "rho"] = rho
corr_spearman_Phylum_PCO[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_PCO[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_PCO[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_PCO[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_PCO$p.adjusted <- p.adjust(corr_spearman_Phylum_PCO$p.value, method = "BH", n = 35)
corr_spearman_Phylum_PCO$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_PCO$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_PCO$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_PCO$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_PCO, file = '/Users/student05/Documents/serum lipids/phylum/PCO.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='PCO', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PCO', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PCO', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PCO', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PCO', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PCO', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Phosphatidylethanolamin und phylum-level
In Arbeit
corr_map_phylum_PE <- filter(phylum_LI, !is.na(PE))
corr_spearman_Phylum_PE <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_PE, !is.na(i))
y = tmp[,i]
x = tmp$PE
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$PE
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$PE
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_PE)+1
corr_spearman_Phylum_PE[nrow,"FA"] <- "PE"
corr_spearman_Phylum_PE[nrow, "Phylum"] = i
corr_spearman_Phylum_PE[nrow, "p.value"] = p
corr_spearman_Phylum_PE[nrow, "rho"] = rho
corr_spearman_Phylum_PE[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_PE[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_PE[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_PE[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_PE$p.adjusted <- p.adjust(corr_spearman_Phylum_PE$p.value, method = "BH", n = 35)
corr_spearman_Phylum_PE$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_PE$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_PE$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_PE$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_PE, file = '/Users/student05/Documents/serum lipids/phylum/PE.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='PE', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(10, -0.9), cor.coef.size = 5, xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PE', y='k__Bacteria.p__Bacteroidetes', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(10, -0.9), cor.coef.size = 5, xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
pdf("/Users/student05/Documents/fertige Plots/PE.proteo.pdf",width=8.5, height=10)
ggscatter(phylum_LI, x='PE', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('skyblue', 'orchid'), size = 2.5, add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(15, -1.5), cor.coef.size = 8,xlab= 'Phosphatidylethanolaminkonzentrationen [nmol/ml]', ylab = 'Relatives Vorkommen p__Proteobacteria [%]')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(hjust=1))+
scale_y_log10(labels = percent_format())+
theme(legend.position="none")
dev.off()
ggscatter(phylum_LI, x='PE', y='k__Bacteria.p__Proteobacteria', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]',cor.coef.coord = c(20, -1.4), cor.coef.size = 5, ylab = 'log10 (Relative Abundance p__Proteobacteria)')+theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PE', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PE', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PE', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PE', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Sphingomyelin und phylum-level
corr_map_phylum_SM <- filter(phylum_LI, !is.na(SM))
corr_spearman_Phylum_SM <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_SM, !is.na(i))
y = tmp[,i]
x = tmp$SM
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$SM
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$SM
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_SM)+1
corr_spearman_Phylum_SM[nrow,"FA"] <- "SM"
corr_spearman_Phylum_SM[nrow, "Phylum"] = i
corr_spearman_Phylum_SM[nrow, "p.value"] = p
corr_spearman_Phylum_SM[nrow, "rho"] = rho
corr_spearman_Phylum_SM[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_SM[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_SM[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_SM[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_SM$p.adjusted <- p.adjust(corr_spearman_Phylum_SM$p.value, method = "BH", n = 35)
corr_spearman_Phylum_SM$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_SM$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_SM$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_SM$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_SM, file = '/Users/student05/Documents/serum lipids/phylum/SM.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='SM', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipids concentration [nmol/ml]',cor.coef.coord = c(200, -0.9), cor.coef.size = 4, ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(angle=45, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='SM', y='k__Bacteria.p__Bacteroidetes', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipids concentration [nmol/ml]',cor.coef.coord = c(200, -0.9), cor.coef.size = 4, ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='SM', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='SM', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='SM', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='SM', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='SM', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Phosphatidylinositol und phylum-level
corr_map_phylum_PI <- filter(phylum_LI, !is.na(PI))
corr_spearman_Phylum_PI <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_PI, !is.na(i))
y = tmp[,i]
x = tmp$PI
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$PI
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$PI
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_PI)+1
corr_spearman_Phylum_PI[nrow,"FA"] <- "PI"
corr_spearman_Phylum_PI[nrow, "Phylum"] = i
corr_spearman_Phylum_PI[nrow, "p.value"] = p
corr_spearman_Phylum_PI[nrow, "rho"] = rho
corr_spearman_Phylum_PI[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_PI[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_PI[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_PI[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_PI$p.adjusted <- p.adjust(corr_spearman_Phylum_PI$p.value, method = "BH", n = 35)
corr_spearman_Phylum_PI$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_PI$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_PI$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_PI$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_PI, file = '/Users/student05/Documents/serum lipids/phylum/PI.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='PI', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PI', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PI', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PI', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PI', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PI', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Phosphatidylethanolamin-Plasmalogen und phylum-level
corr_map_phylum_PEP <- filter(phylum_LI, !is.na(PEP))
corr_spearman_Phylum_PEP <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_PEP, !is.na(i))
y = tmp[,i]
x = tmp$PEP
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$PEP
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$PEP
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_PEP)+1
corr_spearman_Phylum_PEP[nrow,"FA"] <- "PEP"
corr_spearman_Phylum_PEP[nrow, "Phylum"] = i
corr_spearman_Phylum_PEP[nrow, "p.value"] = p
corr_spearman_Phylum_PEP[nrow, "rho"] = rho
corr_spearman_Phylum_PEP[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_PEP[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_PEP[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_PEP[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_PEP$p.adjusted <- p.adjust(corr_spearman_Phylum_PEP$p.value, method = "BH", n = 35)
corr_spearman_Phylum_PEP$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_PEP$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_PEP$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_PEP$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_PEP, file = '/Users/student05/Documents/serum lipids/phylum/PEP.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='PEP', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PEP', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PEP', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PEP', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PEP', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PEP', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Lysophosphatidylcholin und phylum-level
corr_map_phylum_LPC <- filter(phylum_LI, !is.na(LPC))
corr_spearman_Phylum_LPC <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_LPC, !is.na(i))
y = tmp[,i]
x = tmp$LPC
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$LPC
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$LPC
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_LPC)+1
corr_spearman_Phylum_LPC[nrow,"FA"] <- "LPC"
corr_spearman_Phylum_LPC[nrow, "Phylum"] = i
corr_spearman_Phylum_LPC[nrow, "p.value"] = p
corr_spearman_Phylum_LPC[nrow, "rho"] = rho
corr_spearman_Phylum_LPC[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_LPC[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_LPC[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_LPC[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_LPC$p.adjusted <- p.adjust(corr_spearman_Phylum_LPC$p.value, method = "BH", n = 35)
corr_spearman_Phylum_LPC$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_LPC$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_LPC$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_LPC$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_LPC, file = '/Users/student05/Documents/serum lipids/phylum/LPC.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='LPC', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='LPC', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='LPC', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='LPC', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='LPC', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='LPC', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Ceramid und phylum-level
corr_map_phylum_CER <- filter(phylum_LI, !is.na(CER))
corr_spearman_Phylum_CER <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_CER, !is.na(i))
y = tmp[,i]
x = tmp$CER
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$CER
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$CER
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_CER)+1
corr_spearman_Phylum_CER[nrow,"FA"] <- "CER"
corr_spearman_Phylum_CER[nrow, "Phylum"] = i
corr_spearman_Phylum_CER[nrow, "p.value"] = p
corr_spearman_Phylum_CER[nrow, "rho"] = rho
corr_spearman_Phylum_CER[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_CER[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_CER[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_CER[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_CER$p.adjusted <- p.adjust(corr_spearman_Phylum_CER$p.value, method = "BH", n = 35)
corr_spearman_Phylum_CER$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_CER$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_CER$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_CER$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_CER, file = '/Users/student05/Documents/serum lipids/phylum/CER.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='CER', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Cer serum lipids concentration [nmol/ml]', cor.coef.coord = c(8, -0.9), cor.coef.size = 6,ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='CER', y='k__Bacteria.p__Bacteroidetes', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Cer serum lipids concentration [nmol/ml]', cor.coef.coord = c(8, -0.9), cor.coef.size = 6,ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='CER', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Cer serum lipids concentration [nmol/ml]',cor.coef.coord = c(8, -0.9), cor.coef.size = 6, ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='CER', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='CER', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='CER', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='CER', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Hexosylceramid und phylum-level
corr_map_phylum_HexCer <- filter(phylum_LI, !is.na(HexCer))
corr_spearman_Phylum_HexCer <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_HexCer, !is.na(i))
y = tmp[,i]
x = tmp$HexCer
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$HexCer
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$HexCer
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_HexCer)+1
corr_spearman_Phylum_HexCer[nrow,"FA"] <- "HexCer"
corr_spearman_Phylum_HexCer[nrow, "Phylum"] = i
corr_spearman_Phylum_HexCer[nrow, "p.value"] = p
corr_spearman_Phylum_HexCer[nrow, "rho"] = rho
corr_spearman_Phylum_HexCer[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_HexCer[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_HexCer[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_HexCer[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_HexCer$p.adjusted <- p.adjust(corr_spearman_Phylum_HexCer$p.value, method = "BH", n = 35)
corr_spearman_Phylum_HexCer$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_HexCer$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_HexCer$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_HexCer$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_HexCer, file = '/Users/student05/Documents/serum lipids/phylum/HexCer.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='HexCer', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, label = 'Proband',
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='HexCer', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='HexCer', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundancep__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='HexCer', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='HexCer', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='HexCer', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen summierten Serumlipiden und phylum-level
corr_map_phylum_Sum <- filter(phylum_LI, !is.na(Sum))
corr_spearman_Phylum_Sum <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_Sum, !is.na(i))
y = tmp[,i]
x = tmp$Sum
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Sum
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Sum
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_Sum)+1
corr_spearman_Phylum_Sum[nrow,"FA"] <- "Sum"
corr_spearman_Phylum_Sum[nrow, "Phylum"] = i
corr_spearman_Phylum_Sum[nrow, "p.value"] = p
corr_spearman_Phylum_Sum[nrow, "rho"] = rho
corr_spearman_Phylum_Sum[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_Sum[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_Sum[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_Sum[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_Sum$p.adjusted <- p.adjust(corr_spearman_Phylum_Sum$p.value, method = "BH", n = 35)
corr_spearman_Phylum_Sum$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_Sum$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_Sum$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_Sum$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_Sum, file = '/Users/student05/Documents/serum lipids/phylum/Sum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='Sum', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen summierten Membranlipiden und phylum-level
corr_map_phylum_Sum.Membrane <- filter(phylum_LI, !is.na(Sum.Membrane))
corr_spearman_Phylum_Sum.Membrane <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_Sum.Membrane, !is.na(i))
y = tmp[,i]
x = tmp$Sum.Membrane
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Sum.Membrane
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Sum.Membrane
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_Sum.Membrane)+1
corr_spearman_Phylum_Sum.Membrane[nrow,"FA"] <- "Sum.Membrane"
corr_spearman_Phylum_Sum.Membrane[nrow, "Phylum"] = i
corr_spearman_Phylum_Sum.Membrane[nrow, "p.value"] = p
corr_spearman_Phylum_Sum.Membrane[nrow, "rho"] = rho
corr_spearman_Phylum_Sum.Membrane[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_Sum.Membrane[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_Sum.Membrane[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_Sum.Membrane[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_Sum.Membrane$p.adjusted <- p.adjust(corr_spearman_Phylum_Sum.Membrane$p.value, method = "BH", n = 35)
corr_spearman_Phylum_Sum.Membrane$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_Sum.Membrane$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_Sum.Membrane$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_Sum.Membrane$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_Sum.Membrane, file = '/Users/student05/Documents/serum lipids/phylum/Sum.Membrane.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='Sum.Membrane', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Membrane', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'Summarized membrane serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Membrane', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Membrane', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Membrane', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Membrane', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen summierten Storagelipiden und phylum-level
corr_map_phylum_Sum.Storage <- filter(phylum_LI, !is.na(Sum.Storage))
corr_spearman_Phylum_Sum.Storage <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_Sum.Storage, !is.na(i))
y = tmp[,i]
x = tmp$Sum.Storage
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Sum.Storage
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Sum.Storage
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_Sum.Storage)+1
corr_spearman_Phylum_Sum.Storage[nrow,"FA"] <- "Sum.Storage"
corr_spearman_Phylum_Sum.Storage[nrow, "Phylum"] = i
corr_spearman_Phylum_Sum.Storage[nrow, "p.value"] = p
corr_spearman_Phylum_Sum.Storage[nrow, "rho"] = rho
corr_spearman_Phylum_Sum.Storage[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_Sum.Storage[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_Sum.Storage[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_Sum.Storage[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_Sum.Storage$p.adjusted <- p.adjust(corr_spearman_Phylum_Sum.Storage$p.value, method = "BH", n = 35)
corr_spearman_Phylum_Sum.Storage$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_Sum.Storage$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_Sum.Storage$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_Sum.Storage$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_Sum.Storage, file = '/Users/student05/Documents/serum lipids/phylum/Sum.Storage.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='Sum.Storage', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'summarized storage serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Storage', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Storage', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'summarized storage serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Storage', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, or.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Storage', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Storage', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen summierten Lysolipiden und phylum-level
corr_map_phylum_Sum.Lyso <- filter(phylum_LI, !is.na(Sum.Lyso))
corr_spearman_Phylum_Sum.Lyso <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_Sum.Lyso, !is.na(i))
y = tmp[,i]
x = tmp$Sum.Lyso
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Sum.Lyso
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Sum.Lyso
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_Sum.Lyso)+1
corr_spearman_Phylum_Sum.Lyso[nrow,"FA"] <- "Sum.Lyso"
corr_spearman_Phylum_Sum.Lyso[nrow, "Phylum"] = i
corr_spearman_Phylum_Sum.Lyso[nrow, "p.value"] = p
corr_spearman_Phylum_Sum.Lyso[nrow, "rho"] = rho
corr_spearman_Phylum_Sum.Lyso[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_Sum.Lyso[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_Sum.Lyso[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_Sum.Lyso[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_Sum.Lyso$p.adjusted <- p.adjust(corr_spearman_Phylum_Sum.Lyso$p.value, method = "BH", n = 35)
corr_spearman_Phylum_Sum.Lyso$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_Sum.Lyso$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_Sum.Lyso$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_Sum.Lyso$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_Sum.Lyso, file = '/Users/student05/Documents/serum lipids/phylum/Sum.Lyso.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='Sum.Lyso', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'summarized lyso serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Lyso', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Lyso', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Lyso', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Lyso', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'summarized lyso serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='Sum.Lyso', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und PLots Korrelation zwischen LPC/PC-Verhältnis und phylum-level
corr_map_phylum_LPC.PC <- filter(phylum_LI, !is.na(LPC.PC))
corr_spearman_Phylum_LPC.PC <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_LPC.PC, !is.na(i))
y = tmp[,i]
x = tmp$LPC.PC
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$LPC.PC
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$LPC.PC
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_LPC.PC)+1
corr_spearman_Phylum_LPC.PC[nrow,"FA"] <- "LPC.PC"
corr_spearman_Phylum_LPC.PC[nrow, "Phylum"] = i
corr_spearman_Phylum_LPC.PC[nrow, "p.value"] = p
corr_spearman_Phylum_LPC.PC[nrow, "rho"] = rho
corr_spearman_Phylum_LPC.PC[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_LPC.PC[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_LPC.PC[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_LPC.PC[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_LPC.PC$p.adjusted <- p.adjust(corr_spearman_Phylum_LPC.PC$p.value, method = "BH", n = 35)
corr_spearman_Phylum_LPC.PC$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_LPC.PC$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_LPC.PC$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_LPC.PC$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_LPC.PC, file = '/Users/student05/Documents/serum lipids/phylum/LPC.PC.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='LPC.PC', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC/PC serum lipids ratio', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='LPC.PC', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC/PC serum lipids ratio', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='LPC.PC', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='LPC.PC', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='LPC.PC', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(0.04, -0.75),xlab= 'LPC/PC serum lipids ratio', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='LPC.PC', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und PLots Korrelation zwischen CER/SM-Verhältnis und phylum-level
corr_map_phylum_CER.SM <- filter(phylum_LI, !is.na(CER.SM))
corr_spearman_Phylum_CER.SM <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_CER.SM, !is.na(i))
y = tmp[,i]
x = tmp$CER.SM
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$CER.SM
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$CER.SM
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_CER.SM)+1
corr_spearman_Phylum_CER.SM[nrow,"FA"] <- "CER.SM"
corr_spearman_Phylum_CER.SM[nrow, "Phylum"] = i
corr_spearman_Phylum_CER.SM[nrow, "p.value"] = p
corr_spearman_Phylum_CER.SM[nrow, "rho"] = rho
corr_spearman_Phylum_CER.SM[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_CER.SM[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_CER.SM[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_CER.SM[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_CER.SM$p.adjusted <- p.adjust(corr_spearman_Phylum_CER.SM$p.value, method = "BH", n = 35)
corr_spearman_Phylum_CER.SM$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_CER.SM$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_CER.SM$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_CER.SM$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_CER.SM, file = '/Users/student05/Documents/serum lipids/phylum/CER.SM.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='CER.SM', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0.02, -0.9), xlab= 'CER/SM serum lipids ratio', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='CER.SM', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER/SM serum lipids ratio', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='CER.SM', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='CER.SM', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='CER.SM', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(0.03, -0.7),xlab= 'CER/SM serum lipids ratio', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='CER.SM', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und PLots Korrelation zwischen HexCER/CER-Verhältnis und phylum-level
corr_map_phylum_HexCer.CER <- filter(phylum_LI, !is.na(HexCer.CER))
corr_spearman_Phylum_HexCer.CER <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_HexCer.CER, !is.na(i))
y = tmp[,i]
x = tmp$HexCer.CER
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$HexCer.CER
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$HexCer.CER
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_HexCer.CER)+1
corr_spearman_Phylum_HexCer.CER[nrow,"FA"] <- "HexCer.CER"
corr_spearman_Phylum_HexCer.CER[nrow, "Phylum"] = i
corr_spearman_Phylum_HexCer.CER[nrow, "p.value"] = p
corr_spearman_Phylum_HexCer.CER[nrow, "rho"] = rho
corr_spearman_Phylum_HexCer.CER[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_HexCer.CER[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_HexCer.CER[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_HexCer.CER[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_HexCer.CER$p.adjusted <- p.adjust(corr_spearman_Phylum_HexCer.CER$p.value, method = "BH", n = 35)
corr_spearman_Phylum_HexCer.CER$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_HexCer.CER$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_HexCer.CER$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_HexCer.CER$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_HexCer.CER, file = '/Users/student05/Documents/serum lipids/phylum/HexCer.CER.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='HexCer.CER', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER/SM serum lipids ratio', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='HexCer.CER', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER/SM serum lipids ratio', ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='HexCer.CER', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='HexCer.CER', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='HexCer.CER', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER/SM serum lipids ratio', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='HexCer.CER', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und PLots Korrelation zwischen PC/PE-Verhältnis und phylum-level In Arbeit
corr_map_phylum_PC.PE <- filter(phylum_LI, !is.na(PC.PE))
corr_spearman_Phylum_PC.PE <- data.frame()
for( i in phylum_colnames) {
tmp <- filter(corr_map_phylum_PC.PE, !is.na(i))
y = tmp[,i]
x = tmp$PC.PE
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$PC.PE
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$PC.PE
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_Phylum_PC.PE)+1
corr_spearman_Phylum_PC.PE[nrow,"FA"] <- "PC.PE"
corr_spearman_Phylum_PC.PE[nrow, "Phylum"] = i
corr_spearman_Phylum_PC.PE[nrow, "p.value"] = p
corr_spearman_Phylum_PC.PE[nrow, "rho"] = rho
corr_spearman_Phylum_PC.PE[nrow, "p.value_PRE"] = p_PRE
corr_spearman_Phylum_PC.PE[nrow, "rho_PRE"] = rho_PRE
corr_spearman_Phylum_PC.PE[nrow, "p.value_POST"] = p_POST
corr_spearman_Phylum_PC.PE[nrow, "rho_POST"] = rho_POST
}
corr_spearman_Phylum_PC.PE$p.adjusted <- p.adjust(corr_spearman_Phylum_PC.PE$p.value, method = "BH", n = 35)
corr_spearman_Phylum_PC.PE$p.adjusted_PRE <- p.adjust(corr_spearman_Phylum_PC.PE$p.value_PRE, method = "BH", n = 35)
corr_spearman_Phylum_PC.PE$p.adjusted_POST <- p.adjust(corr_spearman_Phylum_PC.PE$p.value_POST, method = "BH", n = 35)
write.table(corr_spearman_Phylum_PC.PE, file = '/Users/student05/Documents/serum lipids/phylum/PC.PE.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(phylum_LI, x='PC.PE', y='k__Bacteria.p__Bacteroidetes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER/SM serum lipids ratio', ylab = 'log10 (Relative Abundance p__Bacteroidetes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PC.PE', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC/PE serum lipids ratio',cor.coef.coord = c(30, -1.5), cor.coef.size = 6, ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
pdf("/Users/student05/Documents/fertige Plots/PC.PE.Proteo.pdf",width=8, height=10)
ggscatter(phylum_LI, x='PC.PE', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('skyblue', 'orchid'), size = 2.5, add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(30, -1.7 ), cor.coef.size = 7,xlab= 'PC/PE Verhältnis', ylab = 'Relatives Vorkommen p__Proteobacteria [%]')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(hjust=1))+
scale_y_log10(labels = percent_format())+
theme(legend.position="none")
dev.off()
ggscatter(phylum_LI, x='PC.PE', y='k__Bacteria.p__Proteobacteria', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC/PE serum lipids ratio',cor.coef.coord = c(30, -1.4), cor.coef.size = 6, ylab = 'log10 (Relative Abundance p__Proteobacteria)')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PC.PE', y='k__Bacteria.p__Verrucomicrobia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Verrucomicrobia)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PC.PE', y='k__Bacteria.p__Tenericutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Tenericutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PC.PE', y='k__Bacteria.p__Firmicutes',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER/SM serum lipids ratio', ylab = 'log10 (Relative Abundance p__Firmicutes)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(phylum_LI, x='PC.PE', y='k__Bacteria.p__Actinobacteria',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipids concentration [nmol/ml]', ylab = 'log10 (Relative Abundance p__Actinobacteria)')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 6, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Korrelationsanalysen zwischen Genus-level und Serumlipiden
Subsetten des Genus-level, log-Transformation, hinzufügen von Pseudocount 0.0001 Filtern nach PRE und POST Proben
genus_colnames <- colnames(relab_genus_spread[, c(3:31)])
relab_genus_ID1 <- relab_genus_ID[,c(3:31)] + 0.00001
relab_genus_ID_log <- log10(relab_genus_ID_log)
genus_LI <- cbind(relab_genus_ID1, LI_serum)
genus_LI <- subset(filter(genus_LI, !Proband == '31KE'))
genus_LI <- subset(filter(genus_LI, !Proband == '45GL'))
genus_LI <- subset(filter(genus_LI, !Proband == '34WF'))
genus_LI <- subset(filter(genus_LI, !Proband == '54SL'))
genus_LI <- subset(filter(genus_LI, !Proband == '74SA'))
genus_LI$Time <- factor(genus_LI$Time, levels = c("PRE", "POST"))
Loop und Plots Korrelation zwischen Phosphatidylcholin und genus-level
corr_map_genus_PC <- filter(genus_LI, !is.na(PC))
corr_spearman_genus_PC <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_PC, !is.na(i))
y = tmp[,i]
x = tmp$PC
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$PC
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$PC
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_PC)+1
corr_spearman_genus_PC[nrow,"FA"] = "PC"
corr_spearman_genus_PC[nrow, "Genus"] = i
corr_spearman_genus_PC[nrow, "p.value"] = p
corr_spearman_genus_PC[nrow, "rho"] = rho
corr_spearman_genus_PC[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_PC[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_PC[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_PC[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_PC$p.adjusted <- p.adjust(corr_spearman_genus_PC$p.value, method = "BH", n = 35)
corr_spearman_genus_PC$p.adjusted_PRE <- p.adjust(corr_spearman_genus_PC$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_PC$p.adjusted_POST <- p.adjust(corr_spearman_genus_PC$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_PC, file = '/Users/student05/Documents/serum lipids/genus/PC.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC serum lipid concentration [nmol/ml]', cor.coef.coord = c(800, -1.6), cor.coef.size = 6,ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC serum lipid concentration [nmol/ml]', cor.coef.coord = c(800, -1.6), cor.coef.size = 6,ylab = 'log10 (Relative Abundance g__Coprococcus')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC serum lipid concentration [nmol/ml]',cor.coef.coord = c(800, -2), cor.coef.size = 6, ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC serum lipid concentration [nmol/ml]',cor.coef.coord = c(800, -2), cor.coef.size = 6, ylab = 'log10 (Relative Abundance g__Sutterella')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Phosphatidylcholin-Plasmalogen und genus-level
corr_map_genus_PCO <- filter(genus_LI, !is.na(PCO))
corr_spearman_genus_PCO <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_PCO, !is.na(i))
y = tmp[,i]
x = tmp$PCO
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$PCO
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$PCO
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_PCO)+1
corr_spearman_genus_PCO[nrow,"FA"] = "PCO"
corr_spearman_genus_PCO[nrow, "Genus"] = i
corr_spearman_genus_PCO[nrow, "p.value"] = p
corr_spearman_genus_PCO[nrow, "rho"] = rho
corr_spearman_genus_PCO[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_PCO[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_PCO[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_PCO[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_PCO$p.adjusted <- p.adjust(corr_spearman_genus_PCO$p.value, method = "BH", n = 35)
corr_spearman_genus_PCO$p.adjusted_PRE <- p.adjust(corr_spearman_genus_PCO$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_PCO$p.adjusted_POST <- p.adjust(corr_spearman_genus_PCO$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_PCO, file = '/Users/student05/Documents/serum lipids/genus/PCO.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='PCO', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PCO', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PCO', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PCO', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PCO', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PCO', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PCO', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PCO', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PCO', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PCO serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Sphingomyelin und genus-level
corr_map_genus_SM <- filter(genus_LI, !is.na(SM))
corr_spearman_genus_SM <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_SM, !is.na(i))
y = tmp[,i]
x = tmp$SM
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$SM
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$SM
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_SM)+1
corr_spearman_genus_SM[nrow,"FA"] = "SM"
corr_spearman_genus_SM[nrow, "Genus"] = i
corr_spearman_genus_SM[nrow, "p.value"] = p
corr_spearman_genus_SM[nrow, "rho"] = rho
corr_spearman_genus_SM[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_SM[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_SM[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_SM[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_SM$p.adjusted <- p.adjust(corr_spearman_genus_SM$p.value, method = "BH", n = 35)
corr_spearman_genus_SM$p.adjusted_PRE <- p.adjust(corr_spearman_genus_SM$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_SM$p.adjusted_POST <- p.adjust(corr_spearman_genus_SM$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_SM, file = '/Users/student05/Documents/serum lipids/genus/SM.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipid concentration [nmol/ml]',cor.coef.size = 6,cor.coef.coord = c(200, -1.5), ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipid concentration [nmol/ml]',cor.coef.size = 6,cor.coef.coord = c(200, -1.5), ylab = 'log10 (Relative Abundance g__Coprococcus')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='SM', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='SM', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='SM', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Phosphatidylethanolamin und genus-level
corr_map_genus_PE <- filter(genus_LI, !is.na(PE))
corr_spearman_genus_PE <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_PE, !is.na(i))
y = tmp[,i]
x = tmp$PE
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$PE
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$PE
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_PE)+1
corr_spearman_genus_PE[nrow,"FA"] = "PE"
corr_spearman_genus_PE[nrow, "Genus"] = i
corr_spearman_genus_PE[nrow, "p.value"] = p
corr_spearman_genus_PE[nrow, "rho"] = rho
corr_spearman_genus_PE[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_PE[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_PE[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_PE[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_PE$p.adjusted <- p.adjust(corr_spearman_genus_PE$p.value, method = "BH", n = 35)
corr_spearman_genus_PE$p.adjusted_PRE <- p.adjust(corr_spearman_genus_PE$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_PE$p.adjusted_POST <- p.adjust(corr_spearman_genus_PE$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_PE, file = '/Users/student05/Documents/serum lipids/genus/PE.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='PE', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PE', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PE', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PE', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PE', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PE', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PE', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PE', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PE', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Phosphatidylinositol und genus-level
corr_map_genus_PI <- filter(genus_LI, !is.na(PI))
corr_spearman_genus_PI <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_PI, !is.na(i))
y = tmp[,i]
x = tmp$PI
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$PI
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$PI
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_PI)+1
corr_spearman_genus_PI[nrow,"FA"] = "PI"
corr_spearman_genus_PI[nrow, "Genus"] = i
corr_spearman_genus_PI[nrow, "p.value"] = p
corr_spearman_genus_PI[nrow, "rho"] = rho
corr_spearman_genus_PI[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_PI[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_PI[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_PI[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_PI$p.adjusted <- p.adjust(corr_spearman_genus_PI$p.value, method = "BH", n = 35)
corr_spearman_genus_PI$p.adjusted_PRE <- p.adjust(corr_spearman_genus_PI$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_PI$p.adjusted_POST <- p.adjust(corr_spearman_genus_PI$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_PI, file = '/Users/student05/Documents/serum lipids/genus/PI.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='PI', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PI serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PI', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PI serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PI', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PI serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PI', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PI serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PI', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PI serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PI', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PI serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PI', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PI serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PI', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PI serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PI', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PI serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PI', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PI serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PI', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PI serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Phosphatidylethanolamin-Plasmalogen und genus-level
corr_map_genus_PEP <- filter(genus_LI, !is.na(PEP))
corr_spearman_genus_PEP <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_PEP, !is.na(i))
y = tmp[,i]
x = tmp$PEP
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$PEP
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$PEP
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_PEP)+1
corr_spearman_genus_PEP[nrow,"FA"] = "PEP"
corr_spearman_genus_PEP[nrow, "Genus"] = i
corr_spearman_genus_PEP[nrow, "p.value"] = p
corr_spearman_genus_PEP[nrow, "rho"] = rho
corr_spearman_genus_PEP[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_PEP[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_PEP[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_PEP[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_PEP$p.adjusted <- p.adjust(corr_spearman_genus_PEP$p.value, method = "BH", n = 35)
corr_spearman_genus_PEP$p.adjusted_PRE <- p.adjust(corr_spearman_genus_PEP$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_PEP$p.adjusted_POST <- p.adjust(corr_spearman_genus_PEP$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_PEP, file = '/Users/student05/Documents/serum lipids/genus/PEP.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='PEP', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PEP', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PEP', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PEP', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PEP', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PEP', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PEP', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PEP', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PEP', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PEP', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PEP', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PEP serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Lysophosphatidylcholin und genus-level
corr_map_genus_LPC <- filter(genus_LI, !is.na(LPC))
corr_spearman_genus_LPC <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_LPC, !is.na(i))
y = tmp[,i]
x = tmp$LPC
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$LPC
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$LPC
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_LPC)+1
corr_spearman_genus_LPC[nrow,"FA"] = "LPC"
corr_spearman_genus_LPC[nrow, "Genus"] = i
corr_spearman_genus_LPC[nrow, "p.value"] = p
corr_spearman_genus_LPC[nrow, "rho"] = rho
corr_spearman_genus_LPC[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_LPC[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_LPC[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_LPC[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_LPC$p.adjusted <- p.adjust(corr_spearman_genus_LPC$p.value, method = "BH", n = 35)
corr_spearman_genus_LPC$p.adjusted_PRE <- p.adjust(corr_spearman_genus_LPC$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_LPC$p.adjusted_POST <- p.adjust(corr_spearman_genus_LPC$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_LPC, file = '/Users/student05/Documents/serum lipids/genus/LPC.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='LPC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line',conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Ceramid und genus-level
corr_map_genus_CER <- filter(genus_LI, !is.na(CER))
corr_spearman_genus_CER <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_CER, !is.na(i))
y = tmp[,i]
x = tmp$CER
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$CER
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$CER
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_CER)+1
corr_spearman_genus_CER[nrow,"FA"] = "CER"
corr_spearman_genus_CER[nrow, "Genus"] = i
corr_spearman_genus_CER[nrow, "p.value"] = p
corr_spearman_genus_CER[nrow, "rho"] = rho
corr_spearman_genus_CER[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_CER[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_CER[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_CER[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_CER$p.adjusted <- p.adjust(corr_spearman_genus_CER$p.value, method = "BH", n = 35)
corr_spearman_genus_CER$p.adjusted_PRE <- p.adjust(corr_spearman_genus_CER$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_CER$p.adjusted_POST <- p.adjust(corr_spearman_genus_CER$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_CER, file = '/Users/student05/Documents/serum lipids/genus/CER.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line',conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen Hexosylceramid und genus-level
corr_map_genus_HexCer <- filter(genus_LI, !is.na(HexCer))
corr_spearman_genus_HexCer <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_HexCer, !is.na(i))
y = tmp[,i]
x = tmp$HexCer
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$HexCer
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$HexCer
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_HexCer)+1
corr_spearman_genus_HexCer[nrow,"FA"] = "HexCer"
corr_spearman_genus_HexCer[nrow, "Genus"] = i
corr_spearman_genus_HexCer[nrow, "p.value"] = p
corr_spearman_genus_HexCer[nrow, "rho"] = rho
corr_spearman_genus_HexCer[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_HexCer[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_HexCer[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_HexCer[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_HexCer$p.adjusted <- p.adjust(corr_spearman_genus_HexCer$p.value, method = "BH", n = 35)
corr_spearman_genus_HexCer$p.adjusted_PRE <- p.adjust(corr_spearman_genus_HexCer$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_HexCer$p.adjusted_POST <- p.adjust(corr_spearman_genus_HexCer$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_HexCer, file = '/Users/student05/Documents/serum lipids/genus/HexCer.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line',conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Prevotellaceae.g__Prevotella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE, label= 'Proband',
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Prevotella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen summierten Serumlipiden und genus-level
corr_map_genus_Sum <- filter(genus_LI, !is.na(Sum))
corr_spearman_genus_Sum <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_Sum, !is.na(i))
y = tmp[,i]
x = tmp$Sum
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Sum
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Sum
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_Sum)+1
corr_spearman_genus_Sum[nrow,"FA"] = "Sum"
corr_spearman_genus_Sum[nrow, "Genus"] = i
corr_spearman_genus_Sum[nrow, "p.value"] = p
corr_spearman_genus_Sum[nrow, "rho"] = rho
corr_spearman_genus_Sum[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_Sum[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_Sum[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_Sum[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_Sum$p.adjusted <- p.adjust(corr_spearman_genus_Sum$p.value, method = "BH", n = 35)
corr_spearman_genus_Sum$p.adjusted_PRE <- p.adjust(corr_spearman_genus_Sum$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_Sum$p.adjusted_POST <- p.adjust(corr_spearman_genus_Sum$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_Sum, file = '/Users/student05/Documents/serum lipids/genus/Sum.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line',conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen summierten Membranlipiden und genus-level
corr_map_genus_Sum.Membrane <- filter(genus_LI, !is.na(Sum.Membrane))
corr_spearman_genus_Sum.Membrane <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_Sum.Membrane, !is.na(i))
y = tmp[,i]
x = tmp$Sum.Membrane
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Sum.Membrane
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Sum.Membrane
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_Sum.Membrane)+1
corr_spearman_genus_Sum.Membrane[nrow,"FA"] = "Sum.Membrane"
corr_spearman_genus_Sum.Membrane[nrow, "Genus"] = i
corr_spearman_genus_Sum.Membrane[nrow, "p.value"] = p
corr_spearman_genus_Sum.Membrane[nrow, "rho"] = rho
corr_spearman_genus_Sum.Membrane[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_Sum.Membrane[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_Sum.Membrane[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_Sum.Membrane[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_Sum.Membrane$p.adjusted <- p.adjust(corr_spearman_genus_Sum.Membrane$p.value, method = "BH", n = 35)
corr_spearman_genus_Sum.Membrane$p.adjusted_PRE <- p.adjust(corr_spearman_genus_Sum.Membrane$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_Sum.Membrane$p.adjusted_POST <- p.adjust(corr_spearman_genus_Sum.Membrane$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_Sum.Membrane, file = '/Users/student05/Documents/serum lipids/genus/Sum.Membrane.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line',conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Membrane', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Membrane serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen summierten Storagelipiden und genus-level
corr_map_genus_Sum.Storage <- filter(genus_LI, !is.na(Sum.Storage))
corr_spearman_genus_Sum.Storage <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_Sum.Storage, !is.na(i))
y = tmp[,i]
x = tmp$Sum.Storage
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Sum.Storage
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Sum.Storage
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_Sum.Storage)+1
corr_spearman_genus_Sum.Storage[nrow,"FA"] = "Sum.Storage"
corr_spearman_genus_Sum.Storage[nrow, "Genus"] = i
corr_spearman_genus_Sum.Storage[nrow, "p.value"] = p
corr_spearman_genus_Sum.Storage[nrow, "rho"] = rho
corr_spearman_genus_Sum.Storage[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_Sum.Storage[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_Sum.Storage[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_Sum.Storage[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_Sum.Storage$p.adjusted <- p.adjust(corr_spearman_genus_Sum.Storage$p.value, method = "BH", n = 35)
corr_spearman_genus_Sum.Storage$p.adjusted_PRE <- p.adjust(corr_spearman_genus_Sum.Storage$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_Sum.Storage$p.adjusted_POST <- p.adjust(corr_spearman_genus_Sum.Storage$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_Sum.Storage, file = '/Users/student05/Documents/serum lipids/genus/Sum.Storage.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line',conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Storage', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Storage serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen summierten Lysolipiden und genus-level
corr_map_genus_Sum.Lyso <- filter(genus_LI, !is.na(Sum.Lyso))
corr_spearman_genus_Sum.Lyso <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_Sum.Lyso, !is.na(i))
y = tmp[,i]
x = tmp$Sum.Lyso
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$Sum.Lyso
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$Sum.Lyso
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_Sum.Lyso)+1
corr_spearman_genus_Sum.Lyso[nrow,"FA"] = "Sum.Lyso"
corr_spearman_genus_Sum.Lyso[nrow, "Genus"] = i
corr_spearman_genus_Sum.Lyso[nrow, "p.value"] = p
corr_spearman_genus_Sum.Lyso[nrow, "rho"] = rho
corr_spearman_genus_Sum.Lyso[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_Sum.Lyso[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_Sum.Lyso[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_Sum.Lyso[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_Sum.Lyso$p.adjusted <- p.adjust(corr_spearman_genus_Sum.Lyso$p.value, method = "BH", n = 35)
corr_spearman_genus_Sum.Lyso$p.adjusted_PRE <- p.adjust(corr_spearman_genus_Sum.Lyso$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_Sum.Lyso$p.adjusted_POST <- p.adjust(corr_spearman_genus_Sum.Lyso$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_Sum.Lyso, file = '/Users/student05/Documents/serum lipids/genus/Sum.Lyso.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line',conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(50, -1.5), xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='Sum.Lyso', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'Sum.Lyso serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen LPC/PE-Verhältnis und genus-level
corr_map_genus_LPC.PC <- filter(genus_LI, !is.na(LPC.PC))
corr_spearman_genus_LPC.PC <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_LPC.PC, !is.na(i))
y = tmp[,i]
x = tmp$LPC.PC
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$LPC.PC
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$LPC.PC
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_LPC.PC)+1
corr_spearman_genus_LPC.PC[nrow,"FA"] = "LPC.PC"
corr_spearman_genus_LPC.PC[nrow, "Genus"] = i
corr_spearman_genus_LPC.PC[nrow, "p.value"] = p
corr_spearman_genus_LPC.PC[nrow, "rho"] = rho
corr_spearman_genus_LPC.PC[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_LPC.PC[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_LPC.PC[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_LPC.PC[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_LPC.PC$p.adjusted <- p.adjust(corr_spearman_genus_LPC.PC$p.value, method = "BH", n = 35)
corr_spearman_genus_LPC.PC$p.adjusted_PRE <- p.adjust(corr_spearman_genus_LPC.PC$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_LPC.PC$p.adjusted_POST <- p.adjust(corr_spearman_genus_LPC.PC$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_LPC.PC, file = '/Users/student05/Documents/serum lipids/genus/LPC.PC.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC/PC serum lipid ratio', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line',conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC.PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC.PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Actinobacteria.c__Actinobacteria.o__Bifidobacteriales.f__Bifidobacteriaceae.g__Bifidobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman',cor.coef.coord = c(0.03, -1), xlab= 'LPC/PC serum lipid ratio', ylab = 'log10 (Relative Abundance g__Bifidobacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC.PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC.PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC.PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC.PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC.PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC.PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC.PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC.PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC.PC serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Porphyromonadaceae.g__Parabacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC/PC serum lipid ratio', ylab = 'log10 (Relative Abundance g__Parabacteroides')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='LPC.PC', y='k__Bacteria.p__Actinobacteria.c__Coriobacteriia.o__Coriobacteriales.f__Coriobacteriaceae.g__Collinsella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'LPC/PC serum lipid ratio', ylab = 'log10 (Relative Abundance g__Lachnospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen CER/SM-Verhältnis und genus-level
corr_map_genus_CER.SM <- filter(genus_LI, !is.na(CER.SM))
corr_spearman_genus_CER.SM <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_CER.SM, !is.na(i))
y = tmp[,i]
x = tmp$CER.SM
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$CER.SM
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$CER.SM
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_CER.SM)+1
corr_spearman_genus_CER.SM[nrow,"FA"] = "CER.SM"
corr_spearman_genus_CER.SM[nrow, "Genus"] = i
corr_spearman_genus_CER.SM[nrow, "p.value"] = p
corr_spearman_genus_CER.SM[nrow, "rho"] = rho
corr_spearman_genus_CER.SM[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_CER.SM[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_CER.SM[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_CER.SM[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_CER.SM$p.adjusted <- p.adjust(corr_spearman_genus_CER.SM$p.value, method = "BH", n = 35)
corr_spearman_genus_CER.SM$p.adjusted_PRE <- p.adjust(corr_spearman_genus_CER.SM$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_CER.SM$p.adjusted_POST <- p.adjust(corr_spearman_genus_CER.SM$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_CER.SM, file = '/Users/student05/Documents/serum lipids/genus/CER.SM.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='CER.SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER.SM serum lipid ratio', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER.SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line',conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER.SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER.SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER.SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER.SM', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER.SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER.SM', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER.SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER.SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER.SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER.SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER.SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER.SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER.SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER.SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER.SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER.SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER.SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER.SM', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER.SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='CER.SM', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Clostridiaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'CER.SM serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen HexCer/CER-Verhältnis und genus-level
corr_map_genus_HexCer.CER <- filter(genus_LI, !is.na(HexCer.CER))
corr_spearman_genus_HexCer.CER <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_HexCer.CER, !is.na(i))
y = tmp[,i]
x = tmp$HexCer.CER
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$HexCer.CER
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$HexCer.CER
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_HexCer.CER)+1
corr_spearman_genus_HexCer.CER[nrow,"FA"] = "HexCer.CER"
corr_spearman_genus_HexCer.CER[nrow, "Genus"] = i
corr_spearman_genus_HexCer.CER[nrow, "p.value"] = p
corr_spearman_genus_HexCer.CER[nrow, "rho"] = rho
corr_spearman_genus_HexCer.CER[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_HexCer.CER[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_HexCer.CER[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_HexCer.CER[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_HexCer.CER$p.adjusted <- p.adjust(corr_spearman_genus_HexCer.CER$p.value, method = "BH", n = 35)
corr_spearman_genus_HexCer.CER$p.adjusted_PRE <- p.adjust(corr_spearman_genus_HexCer.CER$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_HexCer.CER$p.adjusted_POST <- p.adjust(corr_spearman_genus_HexCer.CER$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_HexCer.CER, file = '/Users/student05/Documents/serum lipids/genus/HexCer.CER.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='HexCer.CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer.CER serum lipid ratio', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer.CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line',conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer.CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer.CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer.CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer.CER', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer.CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer.CER', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer.CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer.CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer.CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer.CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer.CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer.CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Phascolarctobacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer.CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer.CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer.CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer.CER', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer.CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer.CER', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer.CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='HexCer.CER', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'HexCer.CER serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
Loop und Plots Korrelation zwischen PC/PE-Verhältnis und genus-level
In Arbeit
corr_map_genus_PC.PE <- filter(genus_LI, !is.na(PC.PE))
corr_spearman_genus_PC.PE <- data.frame()
for( i in genus_colnames) {
tmp <- filter(corr_map_genus_PC.PE, !is.na(i))
y = tmp[,i]
x = tmp$PC.PE
tmp_corr_spearman <- cor.test(x, y, method="spearman")
rho = tmp_corr_spearman$estimate
p = tmp_corr_spearman$p.value
z = subset(filter(tmp, Time == "PRE"))[,i]
w = subset(filter(tmp, Time == "PRE"))$PC.PE
tmp_corr_spearman_PRE <- cor.test(z, w, method="spearman")
rho_PRE = tmp_corr_spearman_PRE$estimate
p_PRE = tmp_corr_spearman_PRE$p.value
r = subset(filter(tmp, Time == "POST"))[,i]
s = subset(filter(tmp, Time == "POST"))$PC.PE
tmp_corr_spearman_POST <- cor.test(r, s, method="spearman")
rho_POST = tmp_corr_spearman_POST$estimate
p_POST = tmp_corr_spearman_POST$p.value
nrow = nrow(corr_spearman_genus_PC.PE)+1
corr_spearman_genus_PC.PE[nrow,"FA"] = "PC.PE"
corr_spearman_genus_PC.PE[nrow, "Genus"] = i
corr_spearman_genus_PC.PE[nrow, "p.value"] = p
corr_spearman_genus_PC.PE[nrow, "rho"] = rho
corr_spearman_genus_PC.PE[nrow, "p.value_PRE"] = p_PRE
corr_spearman_genus_PC.PE[nrow, "rho_PRE"] = rho_PRE
corr_spearman_genus_PC.PE[nrow, "p.value_POST"] = p_POST
corr_spearman_genus_PC.PE[nrow, "rho_POST"] = rho_POST
}
corr_spearman_genus_PC.PE$p.adjusted <- p.adjust(corr_spearman_genus_PC.PE$p.value, method = "BH", n = 35)
corr_spearman_genus_PC.PE$p.adjusted_PRE <- p.adjust(corr_spearman_genus_PC.PE$p.value_PRE, method = "BH", n = 35)
corr_spearman_genus_PC.PE$p.adjusted_POST <- p.adjust(corr_spearman_genus_PC.PE$p.value_POST, method = "BH", n = 35)
write.table( corr_spearman_genus_PC.PE, file = '/Users/student05/Documents/serum lipids/genus/PC.PE.txt', sep ="\t", col.names = TRUE,row.names = FALSE)
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Oscillospira',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC/PE serum lipid ratio', ylab = 'log10 (Relative Abundance g__Oscillospira')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Ruminococcaceae.g__Faecalibacterium',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line',conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC.PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Faecalibacterium')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text( hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Coprococcus', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC.PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Coprococcus')+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Proteobacteria.c__Betaproteobacteria.o__Burkholderiales.f__Alcaligenaceae.g__Sutterella',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC.PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Verrucomicrobia.c__Verrucomicrobiae.o__Verrucomicrobiales.f__Verrucomicrobiaceae.g__Akkermansia',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC.PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Sutterella')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC/PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dorea')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Veillonellaceae.g__Dialister',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC.PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC/PE serum lipid ratio', ylab = 'log10 (Relative Abundance g__Bacteroides')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(hjust=1))+
theme(legend.position="none")
pdf("/Users/student05/Documents/fertige Plots/PC.PE.Proteo.pdf",width=8, height=10)
ggscatter(phylum_LI, x='PC.PE', y='k__Bacteria.p__Proteobacteria',color = 'Time', palette = c('skyblue', 'orchid'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(30, -1.7 ), cor.coef.size = 7,xlab= 'PC/PE Verhältnis', ylab = 'Relatives Vorkommen p__Proteobacteria [%]')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(hjust=1))+
scale_y_log10(labels = percent_format())+
theme(legend.position="none")
dev.off()
genus_LI$Time <- factor(genus_LI$Time, levels = c("PRE", "POST"))
pdf("/Users/student05/Documents/fertige Plots/PC.PE.bacteroides.pdf",width=8, height=10)
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',size = 2.5,color = 'Time', palette = c('skyblue', 'orchid'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', cor.coef.coord = c(30, -1), cor.coef.size = 7,xlab= 'PC/PE Verhältnis', ylab = 'Relatives Vorkommen g__Bacteroides [%]')+
facet_grid(.~ Time, scales = "free_x")+
theme(strip.text.x = element_text(size = 18, colour = "black"))+
theme(text = element_text(size=18),
axis.text.x = element_text(hjust=1))+
scale_y_log10(labels = percent_format())+
theme(legend.position="none")
dev.off()
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__.Ruminococcus.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC.PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Firmicutes.c__Clostridia.o__Clostridiales.f__Lachnospiraceae.g__Dorea',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC.PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC/PE serum lipid concentration [nmol/ml]',cor.coef.coord = c(30, -1.1), cor.coef.size = 6, ylab = 'log10 (Relative Abundance g__Bacteroides')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Bacteroidetes.c__Bacteroidia.o__Bacteroidales.f__Bacteroidaceae.g__Bacteroides', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC/PE serum lipid concentration [nmol/ml]',cor.coef.coord = c(30, -1.1), cor.coef.size = 6, ylab = 'log10 (Relative Abundance g__Bacteroides')+
theme(strip.text.x = element_text(size = 15, colour = "black"))+
theme(text = element_text(size=15),
axis.text.x = element_text(angle=0, hjust=1))+
theme(legend.position="none")
ggscatter(genus_LI, x='PC.PE', y='k__Bacteria.p__Firmicutes.c__Erysipelotrichi.o__Erysipelotrichales.f__Erysipelotrichaceae.g__.Eubacterium.',color = 'Time', palette = c('tomato', 'yellowgreen'), add = 'reg.line', conf.int = TRUE,
cor.coef = TRUE, cor.method = 'spearman', xlab= 'PC.PE serum lipid concentration [nmol/ml]', ylab = 'log10 (Relative Abundance g__Dialster')+
facet_grid(.~ Time,scales = "free_x")+
theme(strip.text.x = element_text(size = 10, colour = "black"))+
theme(text = element_text(size=13),
axis.text.x = element_text(angle=60, hjust=1))+
theme(legend.position="none")
LS0tCnRpdGxlOiAiQmFjaGVsb3JhcmJlaXQgTGVuYSBTUzIwMTkiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAotLS0KClZlcndlbmRldGUgUGFrZXRlIGxhZGVuIHVuZCBpbnN0YWxsaWVyZW4KCmBgYHtyfQppbnN0YWxsLnBhY2thZ2VzKCJ2ZWdhbiIpCmluc3RhbGwucGFja2FnZXMoImRweWxyIikKaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpCmluc3RhbGwucGFja2FnZXMoIm5vcnRlc3QiKQppbnN0YWxsLnBhY2thZ2VzKCJnZ3B1YnIiKQppbnN0YWxsLnBhY2thZ2VzKCJjb3dwbG90IikKaW5zdGFsbC5wYWNrYWdlcygiZ2dzaWduaWYiKQppbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQppbnN0YWxsLnBhY2thZ2VzKCJIbWlzYyIpCmluc3RhbGwucGFja2FnZXMoImNvcnJwbG90IikKaW5zdGFsbC5wYWNrYWdlcygiUGVyZm9ybWFuY2VBbmFseXRpY3MiKQppbnN0YWxsLnBhY2thZ2VzKCJ4dHMiKQppbnN0YWxsLnBhY2thZ2VzKCJxdWFkcHJvZyIpCmluc3RhbGwucGFja2FnZXMoIlJtaXNjIikKCmxpYnJhcnkoImRwbHlyIikKbGlicmFyeSgidmVnYW4iKQpsaWJyYXJ5KCJnZ3Bsb3QyIikKbGlicmFyeSgibm9ydGVzdCIpCmxpYnJhcnkoImJpb21mb3JtYXQiKQpsaWJyYXJ5KCJnZ3B1YnIiKQpsaWJyYXJ5KCJjb3dwbG90IikKbGlicmFyeSgiZ2dzaWduaWYiKQpsaWJyYXJ5KCJyZXNoYXBlMiIpCmxpYnJhcnkoInRpZHl2ZXJzZSIpCmxpYnJhcnkoIkhtaXNjIikKbGlicmFyeSgiY29ycnBsb3QiKQpsaWJyYXJ5KCJQZXJmb3JtYW5jZUFuYWx5dGljcyIpCmxpYnJhcnkoInh0cyIpCmBgYAoKMS5TQ0ZBIEFuYWx5c2UgCjEuMSBOb3JtYWx2ZXJ0ZWlsdW5nCgpgYGB7cn0KU0NGQV9zdG9vbCA8LSByZWFkLnRhYmxlKCIvVXNlcnMvc3R1ZGVudDA1L0Rvd25sb2Fkcy9TQ0ZBX3N0b29sIHRvdGFsIFNDRkEudHh0Iiwgc2VwID0gJ1x0JywgY29tbWVudD0nJyxoZWFkPVQsIHJvdy5uYW1lcyA9IDEpCgpWaWV3KFNDRkFfc3Rvb2wpCgpTQ0ZBX3N0b29sPC0gYWRkLnJvd25hbWVzKFNDRkFfc3Rvb2wsICJTYW1wbGVJRCIpCgpTQ0ZBX3N0b29sJFRpbWUgPC1mYWN0b3IoU0NGQV9zdG9vbCRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIsICJGT0xMT1dVUCIpKQoKU0NGQV9zdG9vbFsxLDNdPC0gIlBSRSIKClNDRkFfc3Rvb2xbMSw0XTwtICJPVTEiCgpzY2ZhX2NvbG5hbWVzIDwtIGNvbG5hbWVzKFNDRkFfc3Rvb2xbLCBjKDY6MTApXSkKCm5kLlNDRkE8LSBkYXRhX2ZyYW1lKCkKc2NmYQpzY2ZhX2NvbG5hbWVzWzFdCgpmb3IgKGkgaW4gc2NmYV9jb2xuYW1lcykgIHsKICBmaXQgPC0gc2hhcGlyby50ZXN0KGFzLm1hdHJpeChhcy5kYXRhLmZyYW1lKGxhcHBseShTQ0ZBX3N0b29sWyxpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcy5udW1lcmljKSkpKQogIHAgPSBmaXQkcC52YWx1ZQogIG5yb3cgPSBucm93KG5kLlNDRkEpKzEKICBuZC5TQ0ZBW25yb3csICJjb2x1bW4iXSA9IGkKICBuZC5TQ0ZBW25yb3csICJwLnZhbHVlIl0gPSByb3VuZChwLCA0KQp9Cgogc2lnbi5uZF9TQ0ZBIDwtIGZpbHRlcihuZC5TQ0ZBLCBwID4gMC4wNSkKIApnZ3FxcGxvdChTQ0ZBX3N0b29sJEFjZXRhdGUsIHlsYWIgPSAiQWNldGF0ZSBjb25jZW50cmF0aW9uIG5tb2wvbWciLCB4bGFiID0gIlNhbXBsZUlEIikKZ2dxcXBsb3QoU0NGQV9zdG9vbCRJc28uQnV0eXJhdGUsIHlsYWIgPSAiSXNvLUJ1dHlyYXRlIGNvbmNlbnRyYXRpb24gbm1vbC9tZyIsIHhsYWIgPSAiU2FtcGxlSUQiKQpnZ3FxcGxvdChTQ0ZBX3N0b29sJFByb3Bpb25hdGUsIHlsYWIgPSAiUHJvcGlvbmF0ZSBjb25jZW50cmF0aW9uIG5tb2wvbWciLCB4bGFiID0gIlNhbXBsZUlEIikKZ2dxcXBsb3QoU0NGQV9zdG9vbCRCdXR5cmF0ZSwgeWxhYiA9ICJCdXR5cmF0ZSBjb25jZW50cmF0aW9uIG5tb2wvbWciLCB4bGFiID0gIlNhbXBsZUlEIikKIApgYGAKCkZpbHRlcm4gZGVyIFNDRkEtRGF0ZW4gbmFjaCBQUkUgdW5kIFBPU1QgUHJvYmVuCgpgYGB7cn0KU0NGQV9zdG9vbF9wYWlycyA8LSBmaWx0ZXIoU0NGQV9zdG9vbCwgUHJvYmFuZCA9PSAiMDVBUCIgfCBQcm9iYW5kID09ICIwNldUIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIwN1JXIiB8IFByb2JhbmQgPT0gIjEzQlMiIHwgUHJvYmFuZCA9PSAiMTdTSyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMjJXUyIgfCBQcm9iYW5kID09ICIyNUZFIiB8IFByb2JhbmQgPT0gIjI2RkIiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjI4SE0iIHwgUHJvYmFuZCA9PSAiMjlNSyIgfCBQcm9iYW5kID09ICIzMEhCIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzMUtFIiB8IFByb2JhbmQgPT0gIjMyRkciIHwgUHJvYmFuZCA9PSAiMzZFUiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzdTRCIgfCBQcm9iYW5kID09ICIzOEFSIiB8IFByb2JhbmQgPT0gIjQwV0EiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjQxTUwiIHwgUHJvYmFuZCA9PSAiNDVHTCIgfCBQcm9iYW5kID09ICI0N09UIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI1MERNIiB8IFByb2JhbmQgPT0gIjUzQkQiIHwgUHJvYmFuZCA9PSAiNTRTTCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNTdNVCIgfCBQcm9iYW5kID09ICI2OUhMIiB8IFByb2JhbmQgPT0gIjc0U0EiKQoKCgoKU0NGQV9zdG9vbF9wYWlyc19QUCA8LSBmaWx0ZXIoU0NGQV9zdG9vbF9wYWlycywgVGltZT09IlBSRSIgfCBUaW1lPT0iUE9TVCIpCgoKClNDRkFfc3Rvb2xfcGFpcnNfUFBGVSA8LSBmaWx0ZXIoU0NGQV9zdG9vbCwgUHJvYmFuZCA9PSAiMDVBUCIgfCBQcm9iYW5kID09ICIxMwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQlMiIHwgUHJvYmFuZCA9PSAiMTdTSyIgfCBQcm9iYW5kID09ICIyMldTIiB8IFByb2JhbmQgPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNDBXQSIgfCBQcm9iYW5kID09ICI0MU1MIiB8IFByb2JhbmQgPT0gIjU0U0wiKQoKYGBgCgpXaWxjb3hvbi1UZXN0IHp3aXNjaGVuIGRlbiBaZWl0cHVua3RlbiBkZXIgU0NGQQoKUFJFIHVuZCBQT1NUCmBgYHtyfQp3aWxjb3hfU0NGQTwtIGRhdGFfZnJhbWUoKQoKZm9yIChpIGluIHNjZmFfY29sbmFtZXMpIHsKICAKdG1wPC0gZmlsdGVyKFNDRkFfc3Rvb2xfcGFpcnNfUFBbICxpXSkKICAKICB4IDwtIGFzLm1hdHJpeChhcy5kYXRhLmZyYW1lKGxhcHBseSh0bXBbLGldLCBhcy5udW1lcmljKSkpCiAgCiAgeSA8LSBTQ0ZBX3N0b29sX3BhaXJzX1BQJFRpbWUgCiAgCiAgdG1wX3dpbGNveCA8LSBwYWlyd2lzZS53aWxjb3gudGVzdCh4LCB5LCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBUUlVFKQogIAogIHAgPC0gdG1wX3dpbGNveCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3cod2lsY294X1NDRkEpKzEKICAKICB3aWxjb3hfU0NGQVtucm93LCAiU0NGQSJdIDwtIGkKCiAgd2lsY294X1NDRkFbbnJvdywgIk1lYW4gUFJFIl0gPC0gcm91bmQoYXBwbHkoc3Vic2V0KGZpbHRlcihTQ0ZBX3N0b29sX3BhaXJzLCBUaW1lID09ICJQUkUiKVssaV0sIG5hLnJtID0gVFJVRSksIDIsIG1lYW4sIG5hLnJtID0gVFJVRSksIDQpCiAgCiAgd2lsY294X1NDRkFbbnJvdywgInNkIFBSRSJdIDwtIHJvdW5kKGFwcGx5KHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbF9wYWlycyxUaW1lID09ICJQUkUiKVssaV0sIG5hLnJtID0gVFJVRSksIDIsIHNkLG5hLnJtID0gVFJVRSksIDQpCiAgCiAgd2lsY294X1NDRkFbbnJvdywgIk1lYW4gUE9TVCJdIDwtcm91bmQoYXBwbHkoc3Vic2V0KGZpbHRlcihTQ0ZBX3N0b29sX3BhaXJzLFRpbWUgPT0gIlBPU1QiKVssaV0sIG5hLnJtID0gVFJVRSksIDIsIG1lYW4sbmEucm0gPSBUUlVFKSwgNCkKICAKICB3aWxjb3hfU0NGQVtucm93LCAic2QgUE9TVCJdIDwtIHJvdW5kKGFwcGx5KHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbF9wYWlycyxUaW1lID09ICJQT1NUIilbLGldLCBuYS5ybSA9IFRSVUUpLCAyLCBzZCxuYS5ybSA9IFRSVUUpLCA0KQogIAogIHdpbGNveF9TQ0ZBW25yb3csICJwLnZhbHVlIl0gPC0gcm91bmQocCwgNCkgfQoKYGBgCkFjZXRhdGUgcC52YWx1ZSA9IDAuMDI1IC0+IHNpZ25pZmlrYW50ZXIgVW50ZXJzY2hpZWQhLCBtZWFuIFBSRSA9IDIwNS4zLCBzZCBQUkUgPSAxNDguMywgbWVhbiBQT1NUID0gMTMyLjU4LCBzZCBQT1NUID0gNzkKUHJvcGlvbmF0ZSBwPTAuMTM2IC0+IGtlaW4gc2lnbmlmaWthbnRlciBVbnRlcnNjaGllZCEsIG1lYW4gUFJFID0gNzguNCwgc2QgUFJFID0gNjIuNywgbWVhbiBQT1NUID0gNTQuMywgc2QgUE9TVCA9IDMzLjEgCkJ1dHlyYXRlIHAtdmFsdWUgPSAwLjM0NiAtPiBrZWluIHNpZ25pZmlrYW50ZXIgVW50ZXJzY2hpZWQhLCBtZWFuIFBSRSA9IDU5LjIsIHNkIFBSRSA9IDQxLjQsIG1lYW4gUE9TVCA9IDQ0LjUsIHNkIFBPU1QgPSAyNyAKSXNvYnV0eXJhdGUgcC12YWx1ZSA9IDAuNTcxIC0+IGtlaW4gc2lnbmlmaWthbnRlciBVbnRlcnNjaGllZCEsIG1lYW4gUFJFID0gOS4zOSwgc2QgUFJFID0gNC41NSwgbWVhbiBQT1NUID0gOS4xNywgc2QgUE9TVCA9IDMuMQoKCldpbGNveG9uLVRlc3QgRm9sbG93LXVwCgpgYGB7cn0Kd2lsY294X1NDRkFfRlUgPC0gZGF0YV9mcmFtZSgpCiAgICAgICAKIGZvciAoaSBpbiBzY2ZhX2NvbG5hbWVzKSB7CiAgIAogICB0bXAgPC0gZmlsdGVyKFNDRkFfc3Rvb2xfcGFpcnNfUFBGVVssaV0sICFpcy5uYShpKSkKICAgCiAgIHggPC0gYXMubWF0cml4KGFzLmRhdGEuZnJhbWUobGFwcGx5KHRtcFssaV0sIGFzLm51bWVyaWMpKSkKICAgCiAgIHkgPC0gU0NGQV9zdG9vbF9wYWlyc19QUEZVJFRpbWUKICAgCiAgIHRtcF93aWxjb3ggPC0gcGFpcndpc2Uud2lsY294LnRlc3QoeCwgeSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gVFJVRSkKICAgCiAgIHBfUE9TVF9GVSA8LSB0bXBfd2lsY294JHAudmFsdWVbMV0KICAgCiAgIHBfUFJFX0ZVIDwtIHRtcF93aWxjb3gkcC52YWx1ZVsyXQogICAKICAgcF9QUkVfUE9TVCA8LSB0bXBfd2lsY294JHAudmFsdWVbNF0KICAgCiAgIG5yb3cgPSBucm93KHdpbGNveF9TQ0ZBX0ZVKSsxCiAgIAogICB3aWxjb3hfU0NGQV9GVVtucm93LCAiU0NGQSJdIDwtIGkKICAgCiAgIHdpbGNveF9TQ0ZBX0ZVW25yb3csICJNZWFuIEZPTExPV1VQIl0gPC0gcm91bmQoYXBwbHkoc3Vic2V0KGZpbHRlcihTQ0ZBX3N0b29sX3BhaXJzX1BQRlUsIFRpbWUgPT0gIkZPTExPV1VQIilbLGldLCBuYS5ybSA9IFRSVUUpLDIsIG1lYW4sIG5hLnJtID0gVFJVRSksIDQpCiAgIAogIHdpbGNveF9TQ0ZBX0ZVW25yb3csICJzZCBGT0xMT1dVUCJdIDwtIHJvdW5kKGFwcGx5KHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbF9wYWlyc19QUEZVLCBUaW1lID09IkZPTExPV1VQIilbLGldLCBuYS5ybSA9IFRSVUUpLCAyLCBzZCwgbmEucm0gPSBUUlVFKSwgNCkKICAgCiAgIHdpbGNveF9TQ0ZBX0ZVW25yb3csICJwLnZhbHVlX1BPU1RfRlUiXSA8LSByb3VuZChwX1BPU1RfRlUsIDIpCiAgIAogICB3aWxjb3hfU0NGQV9GVVtucm93LCAicC52YWx1ZV9QUkVfRlUiXSA8LSByb3VuZChwX1BSRV9GVSwgMikKICAgCiAgIHdpbGNveF9TQ0ZBX0ZVW25yb3csICJwLnZhbHVlX1BSRV9QT1NUIl0gPC0gcm91bmQocF9QUkVfUE9TVCwgMikKIH0KYGBgCkFjZXRhdGUgcC52YWx1ZVBPU1QvRlUgPSAwLjU2LCBwLnZhbHVlUFJFL0ZVID0gMC40NywgcC52YWx1ZVBSRS9QT1NUID0gMC40NyAtPiBhbGxlcyBrZWluIHNpZ25pZmlrYW50ZXIgVW50ZXJzY2hpZWQhIG1lYW4gRlUgPSAxNzMsIHNkIEZVID0gNDMuNyAKUHJvcGlvbmF0ZSBwLnZhbHVlUE9TVC9GVSA9IDAuOTQsIHAudmFsdWVQUkUvRlUgPSAwLjk0LCBwLnZhbHVlUFJFL1BPU1QgPSAwLjk0IC0+IGFsbGVzIGtlaW4gc2lnbmlmbmlrYW50ZXIgVW50ZXJzY2hpZWQhIG1lYW4gRlUgPSA1OC43LCBzZCBGVT0gMTAuMQpCdXR5cmF0ZSBwLnZhbHVlUE9TVC9GVSA9IDAuNywgcC52YWx1ZVBSRS9GVSA9IDAuNywgcC52YWx1ZVBSRS9QT1NUID0gMC43IC0+IGtlaW4gc2lnbmlmaWthbnRlciBVbnRlcnNjaGllZCBiZWkgYWxsZW4hIG1lYW4gRlUgPSA0My41LCBzZCBGVSA9IDE3LjkKSXNvYnV0eXJhdGUgcC52YWx1ZVBPU1QvRlUgPSAxLCBwLnZhbHVlUFJFL1BPU1QgPSAxLCBwLnZhbHVlUFJFL0ZVID0gMSAtPiBiZWkgYWxsZW4ga2VpbiBzaWduaWZpa2FudGVyIFVudGVyc2NoaWVkISBtZWFuIEZVID0gOS4xNCwgc2QgRlUgPSAyLjEzCgoKUGxvdHRlbiBhbGxlciBTQ0ZBIApBbGxlIFplaXRlbiB6dXNhbW1lbgoKYGBge3J9CgpTQ0ZBX3N0b29sLm1lbHQgPC0gbWVsdChTQ0ZBX3N0b29sX3BhaXJzLCBpZC52YXJzID0gJ1RpbWUnLCBtZWFzdXJlLnZhcnMgPSBjKCdBY2V0YXRlJywgJ1Byb3Bpb25hdGUnLCAnQnV0eXJhdGUnLCAnSXNvLkJ1dHlyYXRlJykpClNDRkFfc3Rvb2wubWVsdCA8LSBzdWJzZXQoZmlsdGVyKFNDRkFfc3Rvb2wubWVsdCwgIVRpbWUgPT0gJ0ZPTExPV1VQJykpClNDRkFfc3Rvb2wubWVsdCA8LSBkcGx5cjo6cmVuYW1lKFNDRkFfc3Rvb2wubWVsdCwgU0NGQT12YXJpYWJsZSkKU0NGQV9zdG9vbC5tZWx0IDwtIGRwbHlyOjpyZW5hbWUoU0NGQV9zdG9vbC5tZWx0LCBDb25jZW50cmF0aW9uPXZhbHVlKQoKcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL1NDRkEuYWxsdGltZXMubmV1LnBkZiIsd2lkdGg9NiwgaGVpZ2h0PTEwKQpnZ3Bsb3QoU0NGQV9zdG9vbC5tZWx0LGFlcyh4PVNDRkEsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gU0NGQSkpICsKICB4bGFiICgnU0NGQScpICsgeWxhYiAoJ0tvbnplbnRyYXRpb25lbiBbwrVtb2wvZ10nKSArIAogIGdlb21fYm94cGxvdCh3aWR0aCA9IC40LCBsd2Q9MSkgICsgdGhlbWVfY2xhc3NpYygpKwogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscyA9IGMoIkFjZXRhdGUiLCAiUHJvcGlvbmF0ZSIsICJCdXR5cmF0ZSIsICJJc28tQnV0eXJhdGUiKSwgdmFsdWVzID0gYygic2VhZ3JlZW40IiwgInNlYWdyZWVuMyIsICJzZWFncmVlbjIiLCAic2VhZ3JlZW4xIikpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKZGV2Lm9mZigpCgpgYGAKClBsb3R0ZW4gZGVyIFNDRkEgamUgWmVpdHB1bmt0CiAKYGBge3J9CgpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvU0NGQS50aW1lcy5wZGYiLHdpZHRoPTYsIGhlaWdodD0xMCkKZ2dwbG90KFNDRkFfc3Rvb2wubWVsdCxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IFNDRkEpKSArCiAgeGxhYiAoJ1plaXRwdW5rdCcpICsgeWxhYiAoJ0tvbnplbnRyYXRpb25lbiBbwrVtb2wvZ10nKSArIAogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuOCwgbHdkPTEpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygiQWNldGF0ZSIsICJQcm9waW9uYXRlIiwgIkJ1dHlyYXRlIiwgIklzby1CdXR5cmF0ZSIpLCB2YWx1ZXMgPSBjKCJzZWFncmVlbjQiLCAic2VhZ3JlZW4zIiwgInNlYWdyZWVuMiIsICJzZWFncmVlbjEiKSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCmRldi5vZmYoKQpgYGAKIApQbG90dGVuIGRlciBlaW56ZWxuZW4gU0NGQQpBY2V0YXQKCmBgYHtyfQpBY2V0YXRlX3N0b29sLm1lbHQgPC0gbWVsdChTQ0ZBX3N0b29sX3BhaXJzLCBpZC52YXJzID0gJ1RpbWUnLCBtZWFzdXJlLnZhcnMgPSBjKCdBY2V0YXRlJykpCkFjZXRhdGVfc3Rvb2wubWVsdCA8LSByZW5hbWUoQWNldGF0ZV9zdG9vbC5tZWx0LCBTQ0ZBPXZhcmlhYmxlKQpBY2V0YXRlX3N0b29sLm1lbHQgPC0gcmVuYW1lKEFjZXRhdGVfc3Rvb2wubWVsdCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCmdncGxvdChBY2V0YXRlX3N0b29sLm1lbHQpICsKICB4bGFiICgnVGltZSBQb2ludCcpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW21nL21sXScpICsKICBnZW9tX2JveHBsb3QoYWVzKHg9VGltZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPVNDRkEpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygiQWNldGF0ZSIpLCB2YWx1ZXMgPSBjKCJ0b21hdG8iKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBsaXN0KGMoIlBSRSIsIlBPU1QiKSkpCgpgYGAKCkJveHBsb3QgbWl0IGplIDIgU0NGQSBqZSBaZWl0cHVua3QsIGxpbmtlZCBieSBQcm9iYW5kcwoKQWNldGF0LVByb3Bpb25hdAoKYGBge3J9ClNDRkFfc3Rvb2xfbWVsdF9BUCA8LW1lbHQoU0NGQV9zdG9vbF9wYWlycywgaWQudmFycyA9IGMoJ1RpbWUnLCdQcm9iYW5kJyksIG1lYXN1cmUudmFycyA9IGMoJ0FjZXRhdGUnLCAnUHJvcGlvbmF0ZScpKQpTQ0ZBX3N0b29sX21lbHRfQVAgPC0gcmVuYW1lKFNDRkFfc3Rvb2xfbWVsdF9BUCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKU0NGQV9zdG9vbF9tZWx0X0FQIDwtIHJlbmFtZShTQ0ZBX3N0b29sX21lbHRfQVAsIFNDRkE9dmFyaWFibGUpCgpnZ3BhaXJlZChTQ0ZBX3N0b29sX21lbHRfQVAsIHg9J1NDRkEnLCB5PSdDb25jZW50cmF0aW9uJywgY29sb3IgPSAnYmxhY2snLCBmaWxsPSAnU0NGQScsCiAgICAgICAgIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywgJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBmYWNldC5ieSA9ICdUaW1lJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFLCBsYWJlbCA9ICdQcm9iYW5kJykgKyAKICB4bGFiKCdTQ0ZBJykgKyB5bGFiKCdDb25jZW50cmF0aW9uIFttZy9tbF0nKSArCnNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJBY2V0YXRlIiwgIlByb3Bpb25hdCIpLCB2YWx1ZXMgPSBjKCJ5ZWxsb3dncmVlbiIsICJzdGVlbGJsdWUyIikpCmBgYAoKQWNldGF0LUJ1dHlyYXQKCmBgYHtyfQpTQ0ZBX3N0b29sX21lbHRfQUIgPC1tZWx0KFNDRkFfc3Rvb2xfcGFpcnMsIGlkLnZhcnMgPSBjKCdUaW1lJywnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdBY2V0YXRlJywgJ0J1dHlyYXRlJykpClNDRkFfc3Rvb2xfbWVsdF9BQiA8LSByZW5hbWUoU0NGQV9zdG9vbF9tZWx0X0FCLCBDb25jZW50cmF0aW9uPXZhbHVlKQpTQ0ZBX3N0b29sX21lbHRfQUIgPC0gcmVuYW1lKFNDRkFfc3Rvb2xfbWVsdF9BQiwgU0NGQT12YXJpYWJsZSkKCgpnZ3BhaXJlZChTQ0ZBX3N0b29sX21lbHRfQUIsIHg9J1NDRkEnLCB5PSdDb25jZW50cmF0aW9uJywgY29sb3IgPSAnYmxhY2snLCBmaWxsPSAnU0NGQScsCiAgICAgICAgIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywgJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBmYWNldC5ieSA9ICdUaW1lJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFLCBsYWJlbCA9ICdQcm9iYW5kJykgKyAKICB4bGFiKCdTQ0ZBJykgKyB5bGFiKCdDb25jZW50cmF0aW9uIFttZy9tbF0nKSArCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoIkFjZXRhdGUiLCAiQnV0eXJhdGUiKSwgdmFsdWVzID0gYygieWVsbG93Z3JlZW4iLCAiY29yYWwyIikpCmBgYAoKQWNldGF0LUlzb2J1dHlyYXQKCmBgYHtyfQpTQ0ZBX3N0b29sX21lbHRfQUkgPC1tZWx0KFNDRkFfc3Rvb2xfcGFpcnMsIGlkLnZhcnMgPSBjKCdUaW1lJywnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdBY2V0YXRlJywgJ0lzby5CdXR5cmF0ZScpKQpTQ0ZBX3N0b29sX21lbHRfQUkgPC0gcmVuYW1lKFNDRkFfc3Rvb2xfbWVsdF9BSSwgQ29uY2VudHJhdGlvbj12YWx1ZSkKU0NGQV9zdG9vbF9tZWx0X0FJIDwtIHJlbmFtZShTQ0ZBX3N0b29sX21lbHRfQUksIFNDRkE9dmFyaWFibGUpCgpnZ3BhaXJlZChTQ0ZBX3N0b29sX21lbHRfQUksIHg9J1NDRkEnLCB5PSdDb25jZW50cmF0aW9uJywgY29sb3IgPSAnYmxhY2snLCBmaWxsPSAnU0NGQScsCiAgICAgICAgIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywgJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBmYWNldC5ieSA9ICdUaW1lJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFLCBsYWJlbCA9ICdQcm9iYW5kJykgKyAKICB4bGFiKCdTQ0ZBJykgKyB5bGFiKCdDb25jZW50cmF0aW9uIFttZy9tbF0nKSsKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiQWNldGF0ZSIsICJJc28uQnV0eXJhdGUiKSwgdmFsdWVzID0gYygieWVsbG93Z3JlZW4iLCAiZGVlcHBpbmsiKSkKYGBgCgpQcm9waW9uYXQtQnV0eXJhdAoKYGBge3J9ClNDRkFfc3Rvb2xfbWVsdF9QQiA8LW1lbHQoU0NGQV9zdG9vbF9wYWlycywgaWQudmFycyA9IGMoJ1RpbWUnLCdQcm9iYW5kJyksIG1lYXN1cmUudmFycyA9IGMoJ1Byb3Bpb25hdGUnLCAnQnV0eXJhdGUnKSkKU0NGQV9zdG9vbF9tZWx0X1BCIDwtIHJlbmFtZShTQ0ZBX3N0b29sX21lbHRfUEIsIENvbmNlbnRyYXRpb249dmFsdWUpClNDRkFfc3Rvb2xfbWVsdF9QQiA8LSByZW5hbWUoU0NGQV9zdG9vbF9tZWx0X1BCLCBTQ0ZBPXZhcmlhYmxlKQoKZ2dwYWlyZWQoU0NGQV9zdG9vbF9tZWx0X1BCLCB4PSdTQ0ZBJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbD0gJ1NDRkEnLAogICAgICAgICBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsICd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgZmFjZXQuYnkgPSAnVGltZScsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSwgbGFiZWwgPSAnUHJvYmFuZCcpICsgCiAgeGxhYignU0NGQScpICsgeWxhYignQ29uY2VudHJhdGlvbiBbbWcvbWxdJykrCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoIlByb3Bpb25hdGUiLCAiQnV0eXJhdGUiKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIsICJjb3JhbDIiKSkKYGBgCgpCdXR5cmF0LUlzb2J1dHlyYXQKCmBgYHtyfQpTQ0ZBX3N0b29sX21lbHRfQkkgPC1tZWx0KFNDRkFfc3Rvb2xfcGFpcnMsIGlkLnZhcnMgPSBjKCdUaW1lJywnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdCdXR5cmF0ZScsICdJc28uQnV0eXJhdGUnKSkKU0NGQV9zdG9vbF9tZWx0X0JJIDwtIHJlbmFtZShTQ0ZBX3N0b29sX21lbHRfQkksIENvbmNlbnRyYXRpb249dmFsdWUpClNDRkFfc3Rvb2xfbWVsdF9CSSA8LSByZW5hbWUoU0NGQV9zdG9vbF9tZWx0X0JJLCBTQ0ZBPXZhcmlhYmxlKQoKZ2dwYWlyZWQoU0NGQV9zdG9vbF9tZWx0X0JJLCB4PSdTQ0ZBJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbD0gJ1NDRkEnLAogICAgICAgICBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsICd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgZmFjZXQuYnkgPSAnVGltZScsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSwgbGFiZWwgPSAnUHJvYmFuZCcpICsgCiAgeGxhYignU0NGQScpICsgeWxhYignQ29uY2VudHJhdGlvbiBbbWcvbWxdJykrCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoIkJ1dHlyYXRlIiwgIklzby5CdXR5cmF0ZSIpLCB2YWx1ZXMgPSBjKCJjb3JhbDIiLCAiZGVlcHBpbmsiKSkKYGBgCgpQcm9waW9uYXQtSXNvYnV0eXJhdAoKYGBge3J9ClNDRkFfc3Rvb2xfbWVsdF9QSSA8LW1lbHQoU0NGQV9zdG9vbF9wYWlycywgaWQudmFycyA9IGMoJ1RpbWUnLCdQcm9iYW5kJyksIG1lYXN1cmUudmFycyA9IGMoJ1Byb3Bpb25hdGUnLCdJc28uQnV0eXJhdGUnKSkKU0NGQV9zdG9vbF9tZWx0X1BJIDwtIHJlbmFtZShTQ0ZBX3N0b29sX21lbHRfUEksIENvbmNlbnRyYXRpb249dmFsdWUpClNDRkFfc3Rvb2xfbWVsdF9QSSA8LSByZW5hbWUoU0NGQV9zdG9vbF9tZWx0X1BJLCBTQ0ZBPXZhcmlhYmxlKQoKIApnZ3BhaXJlZChTQ0ZBX3N0b29sX21lbHRfUEksIHg9J1NDRkEnLCB5PSdDb25jZW50cmF0aW9uJywgY29sb3IgPSAnYmxhY2snLCBmaWxsPSAnU0NGQScsCiAgICAgICAgIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywgJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBmYWNldC5ieSA9ICdUaW1lJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFLCBsYWJlbCA9ICdQcm9iYW5kJykgKyAKICB4bGFiKCdTQ0ZBJykgKyB5bGFiKCdDb25jZW50cmF0aW9uIFttZy9tbF0nKSsKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiUHJvcGlvbmF0ZSIsICJJc28uQnV0eXJhdGUiKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIsICJkZWVwcGluayIpKQpgYGAKCjEuMiBFcnN0ZWxsZW4gZWluZXIgS29ycmVsYXRpb25zbWF0cml4IHp1bSBUZXN0ZW4gdm9uIEtvcnJlbGF0aW9uZW4gendpc2NoZW4gZGVuIFNDRkEKCmBgYHtyfQpTQ0ZBX3N0b29sIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG93bmxvYWRzL1NDRkFfc3Rvb2wgdG90YWwgU0NGQS50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLAogICAgICAgICAgICAgICAgICAgICAgICAgaGVhZD1ULCByb3cubmFtZXMgPSAxKQoKd3JpdGUudGFibGUoU0NGQV9zdG9vbCwgZmlsZSA9Jy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL1NDRkEvU0NGQV9zdG9vbCB0b3RhbCBTQ0ZBLnR4dCcsc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLCByb3cubmFtZXMgPSBGQUxTRSkKCgpWaWV3KFNDRkFfc3Rvb2wpCgpTQ0ZBX3N0b29sPC0gYWRkX3Jvd25hbWVzKFNDRkFfc3Rvb2wsICJTYW1wbGVJRCIpCgpTQ0ZBX3N0b29sJFRpbWUgPC1mYWN0b3IoU0NGQV9zdG9vbCRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIsICJGT0xMT1dVUCIpKQoKU0NGQV9zdG9vbF9tYXRyaXhfUFJFIDwtIHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbCwgVGltZSA9PSAiUFJFIikpWyAsNjoxMF0KU0NGQV9zdG9vbF9tYXRyaXhfUE9TVCA8LSBzdWJzZXQoZmlsdGVyKFNDRkFfc3Rvb2wsIFRpbWUgPT0gIlBPU1QiKSlbICw2OjEwXQoKcmVzLlBSRSA8LSBjb3IoU0NGQV9zdG9vbF9tYXRyaXhfUFJFKQpyZXMuUE9TVCA8LSBjb3IoU0NGQV9zdG9vbF9tYXRyaXhfUE9TVCkKYGBgCgpTcGVhcm1hbi1Lb3JyZWxhdGlvbiAKCmBgYHtyfQpyZXMyLlBSRSA8LSByY29ycihhcy5tYXRyaXgoU0NGQV9zdG9vbF9tYXRyaXhfUFJFKSwgdHlwZSA9ICJzcGVhcm1hbiIpCgpyZXMyLlBPU1QgPC0gcmNvcnIoYXMubWF0cml4KFNDRkFfc3Rvb2xfbWF0cml4X1BPU1QpLCB0eXBlID0gInNwZWFybWFuIikKYGBgCgpLb3JyZWxhdGlvbnNrb2VmZml6aWVudCBiZXN0aW1tZW4KCmBgYHtyfQpyZXMyLlBSRSRyCnJlczIuUE9TVCRyCgpTQ0ZBX3N0b29sX1BSRV9DQyA8LSBhcy5tYXRyaXgoKHJlczIuUFJFJHIpKQpTQ0ZBX3N0b29sX1BPU1RfQ0MgPC0gYXMubWF0cml4KHJlczIuUE9TVCRyKQpgYGAKCnAtdmFsdWVzIGJlc3RpbW1lbgoKYGBge3J9CnJlczIkUAoKU0NGQV9zdG9vbF9QUkVfUFYgPC0gYXMubWF0cml4KHJlczIuUFJFJFApClNDRkFfc3Rvb2xfUE9TVF9QViA8LSBhcy5tYXRyaXgocmVzMi5QT1NUJFApCmBgYAoKZmxhdHRlbkNvcnJNYXRyaXggZXJzdGVsbGVuIGbDvHIgUFJFIHVuZCBQT1NUCgpgYGB7cn0KCmZsYXR0ZW5Db3JyTWF0cml4LlBSRSA8LSBmdW5jdGlvbihTQ0ZBX3N0b29sX1BSRV9DQywgU0NGQV9zdG9vbF9QUkVfUFYpIHsKICB1dCA8LSB1cHBlci50cmkoU0NGQV9zdG9vbF9QUkVfQ0MpCiAgZGF0YS5mcmFtZSgKICAgcm93ID0gcm93bmFtZXMoU0NGQV9zdG9vbF9QUkVfQ0MpW3JvdyhTQ0ZBX3N0b29sX1BSRV9DQylbdXRdXSwKICAgY29sdW1uID0gcm93bmFtZXMoU0NGQV9zdG9vbF9QUkVfQ0MpW2NvbChTQ0ZBX3N0b29sX1BSRV9DQylbdXRdXSwKICAgIGNvciAgPShTQ0ZBX3N0b29sX1BSRV9DQylbdXRdLAogICAgcCA9IFNDRkFfc3Rvb2xfUFJFX1BWW3V0XQogICkKfQoKZmxhdHRlbkNvcnJNYXRyaXguUFJFKHJlczIuUFJFJHIsIHJlczIuUFJFJFApCgoKZmxhdHRlbkNvcnJNYXRyaXguUE9TVCA8LSBmdW5jdGlvbihTQ0ZBX3N0b29sX1BPU1RfQ0MsIFNDRkFfc3Rvb2xfUE9TVF9QVikgewogIHV0IDwtIHVwcGVyLnRyaShTQ0ZBX3N0b29sX1BPU1RfQ0MpCiAgZGF0YS5mcmFtZSgKICAgIHJvdyA9IHJvd25hbWVzKFNDRkFfc3Rvb2xfUE9TVF9DQylbcm93KFNDRkFfc3Rvb2xfUE9TVF9DQylbdXRdXSwKICAgIGNvbHVtbiA9IHJvd25hbWVzKFNDRkFfc3Rvb2xfUE9TVF9DQylbY29sKFNDRkFfc3Rvb2xfUE9TVF9DQylbdXRdXSwKICAgIGNvciAgPShTQ0ZBX3N0b29sX1BPU1RfQ0MpW3V0XSwKICAgIHAgPSBTQ0ZBX3N0b29sX1BPU1RfUFZbdXRdCiAgKQp9CgpmbGF0dGVuQ29yck1hdHJpeC5QT1NUKHJlczIuUE9TVCRyLCByZXMyLlBPU1QkUCkKYGBgCgpEYXRhZnJhbWUgZXJzdGVsbGVuCgpgYGB7cn0KU0NGQV9QUkVfY29yLnAgPC0gYXMuZGF0YS5mcmFtZShmbGF0dGVuQ29yck1hdHJpeC5QUkUocmVzMi5QUkUkciwgcmVzMi5QUkUkUCkpClNDRkFfUE9TVF9jb3IucCA8LSBhcy5kYXRhLmZyYW1lKGZsYXR0ZW5Db3JyTWF0cml4LlBPU1QocmVzMi5QT1NUJHIsIHJlczIuUE9TVCRQKSkKCgpjb2xuYW1lcyhTQ0ZBX1BSRV9jb3IucCkgPC0gYygiU0NGQSIsICJTQ0ZBIiwgImNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IiwgInAtdmFsdWUiKQpjb2xuYW1lcyhTQ0ZBX1BPU1RfY29yLnApIDwtIGMoIlNDRkEiLCAiU0NGQSIsICJjb3JyZWxhdGlvbiBjb2VmZmljaWVudCIsICJwLXZhbHVlIikKYGBgCgpDb3JyZWxvZ3JhbSBlcnN0ZWxsZW4gKFBhY2thZ2UgY29ycnBsb3QpCgpgYGB7cn0KY29ycnBsb3QocmVzLlBSRSwgdHlwZSA9ICJ1cHBlciIsIG9yZGVyID0gImhjbHVzdCIsIAogICAgICAgICB0bC5jb2wgPSAiYmxhY2siLCB0bC5zcnQgPSA0NSkKCmNvcnJwbG90KHJlcy5QT1NULCB0eXBlID0gInVwcGVyIiwgb3JkZXIgPSAiaGNsdXN0IiwgCiAgICAgICAgIHRsLmNvbCA9ICJibGFjayIsIHRsLnNydCA9IDQ1KQoKCmNvcnJwbG90KHJlczIuUFJFJHIsIHR5cGU9InVwcGVyIiwgb3JkZXI9ImhjbHVzdCIsIAogICAgICAgICBwLm1hdCA9IHJlczIuUFJFJFAsIHNpZy5sZXZlbCA9IDAuMDUsIGluc2lnID0gImJsYW5rIikKCmNvcnJwbG90KHJlczIuUFJFJHIsIHR5cGU9InVwcGVyIiwgb3JkZXI9ImhjbHVzdCIsIAogICAgICAgICBwLm1hdCA9IHJlczIuUFJFJFAsIHNpZy5sZXZlbCA9IDAuMDUsIGluc2lnID0gImJsYW5rIikKYGBgCgpTY2F0dGVyIHBsb3RzIGVyc3RlbGxlbgoKYGBge3J9CmNoYXJ0LkNvcnJlbGF0aW9uKFNDRkFfc3Rvb2xfbWF0cml4X1BSRSwgaGlzdG9ncmFtPVRSVUUsIHBjaD0xOSkKY2hhcnQuQ29ycmVsYXRpb24oU0NGQV9zdG9vbF9tYXRyaXhfUE9TVCwgaGlzdG9ncmFtID0gVCwgcGNoID0gMTkpCmBgYAoKaGVhdG1hcCBlcnN0ZWxsZW4KCmBgYHtyfQpjb2w8LSBjb2xvclJhbXBQYWxldHRlKGMoImJsdWUiLCAid2hpdGUiLCAicmVkIikpKDIwKQpoZWF0bWFwKHggPSByZXMuUFJFLCBjb2wgPSBjb2wsIHN5bW0gPSBUUlVFKQpgYGAKCjEuMyBLb3JyZWxhdGlvbmVuIHp3aXNjaGVuIFNDRkEgdW5kIEJhbGxhc3RzdG9mZmF1Zm5haG1lIAoKYGBge3J9ClNDRkFfc3Rvb2wuZiA8LSByZWFkLnRhYmxlKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9TQ0ZBL3NjZmEuZmlicmUudHh0Iiwgc2VwID0gJ1x0JywgY29tbWVudD0nJyxoZWFkPVQsIHJvdy5uYW1lcyA9IDEpCgpTQ0ZBX3N0b29sLmYgPC0gc3Vic2V0KGZpbHRlcihTQ0ZBX3N0b29sLmYsICFQcm9iYW5kID09ICczM01QJykpCgpTQ0ZBX3N0b29sLmZbMSwzXTwtICJQUkUiCgpTQ0ZBX3N0b29sLmYkVGltZSA8LWZhY3RvcihTQ0ZBX3N0b29sLmYkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKYGBgCgpLb3JyZWxhdGlvbmVuIHp3aXNjaGVuIGFsbGVuIFNDRkEgdW5kIEJhbGxhc3RzdG9mZmF1Zm5haG1lIApJbiBBcmJlaXQKCmBgYHtyfQpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvU0NGQS5CYWxsYXN0c3RvZmZlLnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQpnZ3NjYXR0ZXIoU0NGQV9zdG9vbC5mLCB4PSdUb3RhbC5TQ0ZBJywgeT0nRmlicmUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb2xvciA9ICJncmV5NTkiLGZpbGwgPSAibGlnaHRncmF5Iixjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoMCwgODApLGNvci5jb2VmLnNpemUgPSA4LCB4bGFiPSAnR2VzYW10LVNDRkEgS29uemVudHJhdGlvbmVuIFvCtW1vbC9nXScsIHlsYWIgPSAnQmFsbGFzdHN0b2ZmYXVmbmFobWUgW2ddJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIGdlb21fcG9pbnQoY29sb3I9J2JsYWNrJywgc2l6ZT0yLjUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmRldi5vZmYoKQpgYGAKCmNvcnRlc3QgZWluemVsbmUgU0NGQQoKYGBge3J9CmNvci50ZXN0KHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbC5mKSkkVG90YWwuU0NGQSwgc3Vic2V0KGZpbHRlcihTQ0ZBX3N0b29sLmYpKSRGaWJyZSwgbWV0aG9kID0gInNwZWFybWFuIiwgZXhhY3QgPSBGKQpjb3IudGVzdChzdWJzZXQoZmlsdGVyKFNDRkFfc3Rvb2wuZikpJEFjZXRhdGUsIHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbC5mKSkkRmlicmUsIG1ldGhvZCA9ICJzcGVhcm1hbiIsIGV4YWN0ID0gRikKY29yLnRlc3Qoc3Vic2V0KGZpbHRlcihTQ0ZBX3N0b29sLmYpKSRQcm9waW9uYXRlLCBzdWJzZXQoZmlsdGVyKFNDRkFfc3Rvb2wuZikpJEZpYnJlLCBtZXRob2QgPSAic3BlYXJtYW4iLCBleGFjdCA9IEYpCmNvci50ZXN0KHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbC5mKSkkQnV0eXJhdGUsIHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbC5mKSkkRmlicmUsIG1ldGhvZCA9ICJzcGVhcm1hbiIsIGV4YWN0ID0gRikKY29yLnRlc3Qoc3Vic2V0KGZpbHRlcihTQ0ZBX3N0b29sLmYpKSRJc28uQnV0eXJhdGUsIHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbC5mKSkkRmlicmUsIG1ldGhvZCA9ICJzcGVhcm1hbiIsIGV4YWN0ID0gRikKCnAuYWRqdXN0KGMoMC4xNDA3LDAuMTg0NCwwLjI2MTIsIDAuMDYzMzUsIDAuOTg2ICksIG1ldGhvZCA9ICdCSCcsIG49NSkKCmBgYAoKUGxvdHRlbiBBY2V0YXQtQmFsYXNzdHN0b2ZmYXVmbmFobWUKCmBgYHtyfQpnZ3NjYXR0ZXIoU0NGQV9zdG9vbC5mLCB4PSdBY2V0YXRlJywgeT0nRmlicmUnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0FjZXRhdGUgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnRmliZXIgaW50YWtlIFtnXScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIApgYGAKCjEuNCBIaWdoIHVuZCBMb3cgU3Rlcm9sa29udmVydGllcnVuZ3N0eXBlbiBTQ0ZBCgpOYWNoIEtvbnZlcnRpZXJ1bmdzdHlwZW4gZmlsdGVybiB1bmQgUFJFIHVuZCBQT1NUIFByb2JlbiB6dXNhbW1lbmZ1ZWdlbgoKYGBge3J9Cmxvd2NvbnYgPC0gZmlsdGVyKFNDRkFfc3Rvb2wsIFByb2JhbmQgPT0gIjA1QVAiIHwgUHJvYmFuZCA9PSAiMzNNUCIKICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzOEFSIiB8IFByb2JhbmQgPT0gIjQwV0EiIHwgUHJvYmFuZCA9PSAiNDFNTCIKICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI0N09UIiB8IFByb2JhbmQgPT0gIjQ5UkoiIHwgUHJvYmFuZCA9PSAiNTBETSIpCgpsb3djb252WydQaGVub3R5cGUnXSA9ICdsb3cgY29udmVydGVyJwoKaGlnaGNvbnYgPC0gZmlsdGVyKFNDRkFfc3Rvb2wsIFByb2JhbmQgPT0gIjA2V1QiIHwgUHJvYmFuZCA9PSAiMDdSVyIKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjEzQlMiIHwgUHJvYmFuZCA9PSAiMTdTSyIgfCBQcm9iYW5kID09ICIyMldTIgogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMjVGRSIgfCBQcm9iYW5kID09ICIyNkZCIiB8IFByb2JhbmQgPT0gIjI5TUsiCiAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzMEhCIiB8IFByb2JhbmQgPT0gIjMxS0UiIHwgUHJvYmFuZCA9PSAiMzZFUiIKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjQ1R0wiIHwgUHJvYmFuZCA9PSAiNTNCRCIgfCBQcm9iYW5kID09ICI1NFNMIgogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNTdNVCIgfCBQcm9iYW5kID09ICI2OUhMIiB8IFByb2JhbmQgPT0gIjc0U0EiKQoKaGlnaGNvbnZbJ1BoZW5vdHlwZSddID0gJ2hpZ2ggY29udmVydGVyJwoKaGlnaGNvbnYkQ29udmVydGVyLlR5cGUgPC0gTlVMTApsb3djb252JENvbnZlcnRlci5UeXBlIDwtIE5VTEwKCm5vY29udiA8LSBmaWx0ZXIoU0NGQV9zdG9vbCwgUHJvYmFuZCA9PSAiMjhITSIgfCBQcm9iYW5kID09ICIzMkZHIgogICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzNFdGIiB8IFByb2JhbmQgPT0gIjM1QUQiIHwgUHJvYmFuZCA9PSAiMzdTRCIKICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzlEQSIgfCBQcm9iYW5kID09ICI2NkRHIiB8IFByb2JhbmQgPT0gIjcwUEwiKQoKbm9jb252WydQaGVub3R5cGUnXSA9ICdub3QgY2xhc3NpZmllZCcKCm5vY29udiRDb252ZXJ0ZXIuVHlwZSA8LSBOVUxMCgoKY29udlQgPC0gZGF0YS5mcmFtZSgpCmNvbnZUIDwtIGJpbmRfcm93cyhsb3djb252LCBoaWdoY29udiwgbm9jb252KQoKY29udlRfcGFpcmVkIDwtIGZpbHRlcihjb252VCwgUHJvYmFuZCA9PSAiMDVBUCIgfCBQcm9iYW5kID09ICIwNldUIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMDdSVyIgfCBQcm9iYW5kID09ICIxM0JTIiB8IFByb2JhbmQgPT0gIjE3U0siCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIyMldTIiB8IFByb2JhbmQgPT0gIjI1RkUiIHwgUHJvYmFuZCA9PSAiMjZGQiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjI4SE0iIHwgUHJvYmFuZCA9PSAiMjlNSyIgfCBQcm9iYW5kID09ICIzMEhCIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzFLRSIgfCBQcm9iYW5kID09ICIzMkZHIiB8IFByb2JhbmQgPT0gIjM2RVIiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzN1NEIiB8IFByb2JhbmQgPT0gIjM4QVIiIHwgUHJvYmFuZCA9PSAiNDBXQSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjQxTUwiIHwgUHJvYmFuZCA9PSAiNDVHTCIgfCBQcm9iYW5kID09ICI0N09UIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNTBETSIgfCBQcm9iYW5kID09ICI1M0JEIiB8IFByb2JhbmQgPT0gIjU0U0wiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI1N01UIiB8IFByb2JhbmQgPT0gIjY5SEwiIHwgUHJvYmFuZCA9PSAiNzRTQSIpCgoKY29udlRfcGFpcmVkX1BQIDwtIGZpbHRlcihjb252VF9wYWlyZWQsIFRpbWU9PSJQUkUiIHwgVGltZT09IlBPU1QiKQpgYGAKCkJveHBsb3QgU0NGQSBqZSBTdGVyb2xrb252ZXJ0aWVydW5nc3R5cAoKYWxsZSBTQ0ZBCgpgYGB7cn0KU0NGQV9zdG9vbC5tZWx0LkNUIDwtIG1lbHQoY29udlQsIGlkLnZhcnMgPSAnUGhlbm90eXBlJywgbWVhc3VyZS52YXJzID0gYygnQWNldGF0ZScsICdQcm9waW9uYXRlJywgJ0J1dHlyYXRlJywgJ0lzby5CdXR5cmF0ZScpKQpTQ0ZBX3N0b29sLm1lbHQuQ1QgPC0gcmVuYW1lKFNDRkFfc3Rvb2wubWVsdC5DVCwgU0NGQT12YXJpYWJsZSkKU0NGQV9zdG9vbC5tZWx0LkNUIDwtIHJlbmFtZShTQ0ZBX3N0b29sLm1lbHQuQ1QsIENvbmNlbnRyYXRpb249dmFsdWUpCgpnZ3Bsb3QoU0NGQV9zdG9vbC5tZWx0LkNULGFlcyh4PVBoZW5vdHlwZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBTQ0ZBKSkgKwogIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJBY2V0YXRlIiwgIlByb3Bpb25hdGUiLCAiQnV0eXJhdGUiLCAiSXNvLUJ1dHlyYXRlIiksIHZhbHVlcyA9IGMoInRvbWF0byIsICJ5ZWxsb3dncmVlbiIsICJzdGVlbGJsdWUyIiwgIm9yY2hpZDIiKSkKICAKZ2dwbG90KHN1YnNldChmaWx0ZXIoY29udlQsICFQaGVub3R5cGUgPT0gIm5vdCBjbGFzc2lmaWVkIikpLCBhZXMoeD1QaGVub3R5cGUsIHk9QWNldGF0ZSkpICsKICB4bGFiICgnUGhlbm90eXBlJykgKyB5bGFiKCdBY2V0YXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpKwogIGdlb21fYm94cGxvdChmaWxsID0gJ3doaXRlc21va2UnLCBjb2xvciA9ICdibGFjaycpKwogIGdlb21fZG90cGxvdChib25heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4zLCBmaWxsPSAnZ3JleTIyJykKCmBgYAoKQWNldGF0CgpgYGB7cn0KQWNldGF0ZV9zdG9vbC5tZWx0LkNUIDwtIG1lbHQoY29udlRfcGFpcmVkX1BQLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywnVGltZScpLCBtZWFzdXJlLnZhcnMgPSBjKCdBY2V0YXRlJykpCkFjZXRhdGVfc3Rvb2wubWVsdC5DVCA8LSByZW5hbWUoQWNldGF0ZV9zdG9vbC5tZWx0LkNULCBTQ0ZBPXZhcmlhYmxlKQpBY2V0YXRlX3N0b29sLm1lbHQuQ1QgPC0gcmVuYW1lKEFjZXRhdGVfc3Rvb2wubWVsdC5DVCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCmdncGxvdChmaWx0ZXIoQWNldGF0ZV9zdG9vbC5tZWx0LkNULCAhVGltZT09IkZPTExPVy1VUCIgJiAhUGhlbm90eXBlPT0ibm90IGNsYXNzaWZpZWQiKSxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IFNDRkEpKSArCiAgZmFjZXRfZ3JpZCgufiBQaGVub3R5cGUpICsKICB4bGFiICgnVGltZSBQb2ludCcpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiQWNldGF0ZSIpLCB2YWx1ZXMgPSBjKCJ5ZWxsb3dncmVlbiIpKSsKICBnZW9tX2JveHBsb3QoKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFQsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkKICAgICAKYGBgCgpQcm9waW9uYXQKCmBgYHtyfQpQcm9waW9uYXRlX3N0b29sLm1lbHQuQ1QgPC0gbWVsdChjb252VF9wYWlyZWRfUFAsIGlkLnZhcnMgPSBjKCdQaGVub3R5cGUnLCdUaW1lJyksIG1lYXN1cmUudmFycyA9IGMoJ1Byb3Bpb25hdGUnKSkKUHJvcGlvbmF0ZV9zdG9vbC5tZWx0LkNUIDwtIHJlbmFtZShQcm9waW9uYXRlX3N0b29sLm1lbHQuQ1QsIFNDRkE9dmFyaWFibGUpClByb3Bpb25hdGVfc3Rvb2wubWVsdC5DVCA8LSByZW5hbWUoUHJvcGlvbmF0ZV9zdG9vbC5tZWx0LkNULCBDb25jZW50cmF0aW9uPXZhbHVlKQoKZ2dwbG90KGZpbHRlcihQcm9waW9uYXRlX3N0b29sLm1lbHQuQ1QsICFUaW1lPT0iRk9MTE9XLVVQIiAmICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gU0NGQSkpICsKICBmYWNldF9ncmlkKC5+IFBoZW5vdHlwZSkgKwogIHhsYWIgKCdUaW1lIFBvaW50JykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJQcm9waW9uYXQiKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIpKSsKICBnZW9tX2JveHBsb3QoKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFQsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkKCmBgYAoKQnV0eXJhdAoKYGBge3J9CkJ1dHlyYXRlX3N0b29sLm1lbHQuQ1QgPC0gbWVsdChjb252VF9wYWlyZWRfUFAsIGlkLnZhcnMgPSBjKCdQaGVub3R5cGUnLCdUaW1lJyksIG1lYXN1cmUudmFycyA9IGMoJ0J1dHlyYXRlJykpCkJ1dHlyYXRlX3N0b29sLm1lbHQuQ1QgPC0gcmVuYW1lKEJ1dHlyYXRlX3N0b29sLm1lbHQuQ1QsIFNDRkE9dmFyaWFibGUpCkJ1dHlyYXRlX3N0b29sLm1lbHQuQ1QgPC0gcmVuYW1lKEJ1dHlyYXRlX3N0b29sLm1lbHQuQ1QsIENvbmNlbnRyYXRpb249dmFsdWUpCgpnZ3Bsb3QoZmlsdGVyKEJ1dHlyYXRlX3N0b29sLm1lbHQuQ1QsICFUaW1lPT0iRk9MTE9XLVVQIiAmICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gU0NGQSkpICsKICBmYWNldF9ncmlkKC5+IFBoZW5vdHlwZSkgKwogIHhsYWIgKCdUaW1lIFBvaW50JykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJCdXR5cmF0ZSIpLCB2YWx1ZXMgPSBjKCJjb3JhbDIiKSkrCiAgZ2VvbV9ib3hwbG90KCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBULCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpCgpgYGAKSXNvYnV0eXJhdAoKYGBge3J9Cklzby5CdXR5cmF0ZV9zdG9vbC5tZWx0LkNUIDwtIG1lbHQoY29udlRfcGFpcmVkX1BQLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywnVGltZScpLCBtZWFzdXJlLnZhcnMgPSBjKCdJc28uQnV0eXJhdGUnKSkKSXNvLkJ1dHlyYXRlX3N0b29sLm1lbHQuQ1QgPC0gcmVuYW1lKElzby5CdXR5cmF0ZV9zdG9vbC5tZWx0LkNULCBTQ0ZBPXZhcmlhYmxlKQpJc28uQnV0eXJhdGVfc3Rvb2wubWVsdC5DVCA8LSByZW5hbWUoSXNvLkJ1dHlyYXRlX3N0b29sLm1lbHQuQ1QsIENvbmNlbnRyYXRpb249dmFsdWUpCgpnZ3Bsb3QoZmlsdGVyKElzby5CdXR5cmF0ZV9zdG9vbC5tZWx0LkNULCAhVGltZT09IkZPTExPVy1VUCIgJiAhUGhlbm90eXBlPT0ibm90IGNsYXNzaWZpZWQiKSxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IFNDRkEpKSArCiAgZmFjZXRfZ3JpZCgufiBQaGVub3R5cGUpICsKICB4bGFiICgnVGltZSBQb2ludCcpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiSXNvLkJ1dHlyYXRlIiksIHZhbHVlcyA9IGMoImRlZXBwaW5rIikpKwogIGdlb21fYm94cGxvdCgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKQoKYGBgCgpQbG90IHAtdmFsdWUgendpc2NoZW4gU3Rlcm9sY29udmVydGVyIGJlaSBlaW5lbSBaZWl0cHVua3QKCmBgYHtyfQpnZ3Bsb3QoZmlsdGVyKEFjZXRhdGVfc3Rvb2wubWVsdC5DVCwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9VGltZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBTQ0ZBKSkgKwogIGZhY2V0X2dyaWQoLn4gUGhlbm90eXBlKSArCiAgeGxhYiAoJ1RpbWUgUG9pbnQnKSsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoIkFjZXRhdGUiKSwgdmFsdWVzID0gYygieWVsbG93Z3JlZW4iKSkrCiAgZ2VvbV9ib3hwbG90KCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBULCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpCgpnZ3Bsb3QoZmlsdGVyKFByb3Bpb25hdGVfc3Rvb2wubWVsdC5DVCwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9UGhlbm90eXBlLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IFNDRkEpKSArCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSArCiAgeGxhYiAoJ0NvbnZlcnRlciB0eXBlJykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJQcm9waW9uYXRlIiksIHZhbHVlcyA9IGMoInN0ZWVsYmx1ZTIiKSkrCiAgZ2VvbV9ib3hwbG90KCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiaGlnaCBjb252ZXJ0ZXIiLCAibG93IGNvbnZlcnRlciIpKSkKCmdncGxvdChmaWx0ZXIoQnV0eXJhdGVfc3Rvb2wubWVsdC5DVCwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9UGhlbm90eXBlLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IFNDRkEpKSArCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSArCiAgeGxhYiAoJ0NvbnZlcnRlciB0eXBlJykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJCdXR5cmF0ZSIpLCB2YWx1ZXMgPSBjKCJjb3JhbDIiKSkrCiAgZ2VvbV9ib3hwbG90KCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiaGlnaCBjb252ZXJ0ZXIiLCAibG93IGNvbnZlcnRlciIpKSkKCmdncGxvdChmaWx0ZXIoSXNvLkJ1dHlyYXRlX3N0b29sLm1lbHQuQ1QsICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBTQ0ZBKSkgKwogIGZhY2V0X2dyaWQoLn4gVGltZSkgKwogIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiSXNvLkJ1dHlyYXRlIiksIHZhbHVlcyA9IGMoImRlZXBwaW5rIikpKwogIGdlb21fYm94cGxvdCgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gRiwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoImhpZ2ggY29udmVydGVyIiwgImxvdyBjb252ZXJ0ZXIiKSkpCmBgYAoKCjEuNSBEaXZlcnNpdGFldHNhbmFseXNlbiBTQ0ZBLSBTaGFubm9uL1NpbXBzb24KRGF0ZW4gTGFkZW4KCmBgYHtyfQpTQ0ZBX3N0b29sIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG93bmxvYWRzL1NDRkFfc3Rvb2wgdG90YWwgU0NGQS50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLAogICAgICAgICAgICAgICAgICAgICAgICAgaGVhZD1ULCByb3cubmFtZXMgPSAxKQoKbWFwX2FscGhhZGl2IDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3R4dCBkYXRlaWVuIHIvbWVhbnNfYWxwaGFfZGl2LnR4dCIsIHNlcCA9ICdcdCcsIGNvbW1lbnQ9JycsaGVhZCA9IFRSVUUsIHJvdy5uYW1lcyA9IDEpCgpgYGAKCkZpbHRlcm4gZnVlciBQUkUgdW5kIFBPU1QgUHJvYmVuCgpgYGB7cn0KU0NGQV9zdG9vbCRUaW1lIDwtZmFjdG9yKFNDRkFfc3Rvb2wkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiLCAiRk9MTE9XLVVQIikpCgpTQ0ZBX3N0b29sWzEsNF08LSAiT1UxIgoKU0NGQV9zdG9vbF9wYWlycyA8LSBmaWx0ZXIoU0NGQV9zdG9vbCwgUHJvYmFuZCA9PSAiMDVBUCIgfCBQcm9iYW5kID09ICIwNldUIgogICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjA3UlciIHwgUHJvYmFuZCA9PSAiMTNCUyIgfCBQcm9iYW5kID09ICIxN1NLIgogICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjIyV1MiIHwgUHJvYmFuZCA9PSAiMjVGRSIgfCBQcm9iYW5kID09ICIyNkZCIgogICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjI4SE0iIHwgUHJvYmFuZCA9PSAiMjlNSyIgfCBQcm9iYW5kID09ICIzMEhCIgogICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzMkZHIiB8IFByb2JhbmQgPT0gIjM2RVIiICB8IFByb2JhbmQgPT0gIjM1QUQiCiAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzdTRCIgfCBQcm9iYW5kID09ICIzOEFSIiB8IFByb2JhbmQgPT0gIjQwV0EiCiAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNDFNTCIgIHwgUHJvYmFuZCA9PSAiNDdPVCIKICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI1MERNIiB8IFByb2JhbmQgPT0gIjUzQkQiIHwgUHJvYmFuZCA9PSAiNTdNVCIgfCBQcm9iYW5kID09ICI2OUhMIikKCndyaXRlLnRhYmxlKFNDRkFfc3Rvb2xfcGFpcnMsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvU0NGQS9TQ0ZBIGFuYWx5c2UvT1RVIFNDRkEgYW5hbHlzZS9TQ0ZBX3N0b29sLnBhaXJzIFNoYW5ub24gU2ltcHNvbi50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcz0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKClNDRkFfc3Rvb2xfcGFpcnNfUFAgPC0gZmlsdGVyKFNDRkFfc3Rvb2xfcGFpcnMsIFRpbWU9PSJQUkUiIHwgVGltZT09IlBPU1QiKQoKd3JpdGUudGFibGUoU0NGQV9zdG9vbF9wYWlyc19QUCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9TQ0ZBL1NDRkEgYW5hbHlzZS9PVFUgU0NGQSBhbmFseXNlL1NDRkFfc3Rvb2wucGFpcnMuUFAgU2hhbm5vbiBTaW1wc29uLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQpgYGAKClNoYW5ub24gdW5kIFNpbXBzb24gZWluZnVlZ2VuIGluIFNDRkEgRGF0ZW5zYXR6CgpgYGB7cn0KY29tbW9uLmlkcy5TdCA8LSBpbnRlcnNlY3Qocm93bmFtZXMoU0NGQV9zdG9vbCksIHJvd25hbWVzKG1hcF9hbHBoYWRpdikpCmNvbW1vbi5pZHMuU3QgPC0gaW50ZXJzZWN0KHJvdy5uYW1lcyhTQ0ZBX3N0b29sKSwgcm93Lm5hbWVzKG1hcF9hbHBoYWRpdikpCgpTQ0ZBX3N0b29sIDwtIFNDRkFfc3Rvb2xbY29tbW9uLmlkcy5TdCxdCgptYXBfYWxwaGFkaXYgPC0gbWFwX2FscGhhZGl2W2NvbW1vbi5pZHMuU3QsXQoKU0NGQV9zdG9vbCRTaGFubm9uIDwtIG1hcF9hbHBoYWRpdiRTaGFubm9uCgpTQ0ZBX3N0b29sJFNpbXBzb24gPC0gbWFwX2FscGhhZGl2JFNpbXBzb24KYGBgCgpLb3JyZWxhdGlvbnNhbmFseXNlbiB6d2lzY2hlbiBTQ0ZBIHVuZCBTaGFubm9uCkVyc3RlbGxlbiB2b24gTWF0cml4IHVuZCBMb29wLCBmaWx0ZXJuIGZ1ZXIgU2lnbmlmaWthbnoKCgpgYGB7cn0KY29ycl9jb2xuYW1lc19TQ0ZBIDwtY29sbmFtZXMoU0NGQV9zdG9vbFssNjo5XSkKCmNvcnJfc3BlYXJtYW5fU2hhbm5vbl9TQ0ZBIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHVuaXF1ZShjb3JyX2NvbG5hbWVzX1NDRkEpKSB7CiAgCnRtcCA8LSBmaWx0ZXIoU0NGQV9zdG9vbCwgIWlzLm5hKGkpKQogIAp4ID0gYXMubWF0cml4KGFzLmRhdGEuZnJhbWUobGFwcGx5KHRtcFssaV0sIGFzLm51bWVyaWMpKSkKCnkgPSB0KGFzLm1hdHJpeCh0bXAkU2hhbm5vbikgKQogIAp0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKCnJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCnAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCnogPSBhcy5tYXRyaXgoYXMuZGF0YS5mcmFtZShsYXBwbHkoc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0sYXMubnVtZXJpYykpKQogIAp3ID0gdChhcy5tYXRyaXgoc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRTaGFubm9uKSkKICAKdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQoKcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIApwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCgpyID0gYXMubWF0cml4KGFzLmRhdGEuZnJhbWUobGFwcGx5KHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXSxhcy5udW1lcmljKSkpCiAgCnMgPSB0KGFzLm1hdHJpeChzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRTaGFubm9uKSkKICAKdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCnBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQoKYSA9IGFzLm1hdHJpeChhcy5kYXRhLmZyYW1lKGxhcHBseShzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiRk9MTE9XLVVQIikpWyxpXSxhcy5udW1lcmljKSkpCiAgCmIgPSB0KGFzLm1hdHJpeChzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiRk9MTE9XLVVQIikpJFNoYW5ub24pKQogIAp0bXBfY29ycl9zcGVhcm1hbl9GVSA8LSBjb3IudGVzdChhLCBiLCBtZXRob2Q9InNwZWFybWFuIikKICAKcmhvX0ZVID0gdG1wX2NvcnJfc3BlYXJtYW5fRlUkZXN0aW1hdGUKICAKcF9GVSA9IHRtcF9jb3JyX3NwZWFybWFuX0ZVJHAudmFsdWUKIApucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1NoYW5ub25fU0NGQSkrMQoKY29ycl9zcGVhcm1hbl9TaGFubm9uX1NDRkFbbnJvdywiRGl2Il0gPSAiU2hhbm5vbiIKICAKY29ycl9zcGVhcm1hbl9TaGFubm9uX1NDRkFbbnJvdywgImNvbHVtbiJdID0gaQogIApjb3JyX3NwZWFybWFuX1NoYW5ub25fU0NGQVtucm93LCAicmhvIl0gPSByaG8KICAKY29ycl9zcGVhcm1hbl9TaGFubm9uX1NDRkFbbnJvdywgInAudmFsdWUiXSA9IHAKICAKY29ycl9zcGVhcm1hbl9TaGFubm9uX1NDRkFbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKY29ycl9zcGVhcm1hbl9TaGFubm9uX1NDRkFbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIApjb3JyX3NwZWFybWFuX1NoYW5ub25fU0NGQVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCmNvcnJfc3BlYXJtYW5fU2hhbm5vbl9TQ0ZBW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIApjb3JyX3NwZWFybWFuX1NoYW5ub25fU0NGQVtucm93LCAicmhvX0ZVIl0gPSByaG9fRlUKICAKY29ycl9zcGVhcm1hbl9TaGFubm9uX1NDRkFbbnJvdywgInAudmFsdWVfRlUiXSA9IHBfRlUKfQoKY29ycl9zcGVhcm1hbl9TaGFubm9uX1NDRkEkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1NoYW5ub25fU0NGQSRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gNSkKCmNvcnJfc3BlYXJtYW5fU2hhbm5vbl9TQ0ZBJHAuYWRqdXN0ZWRfUFJFIDwtcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9TaGFubm9uX1NDRkEkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSA1KQoKY29ycl9zcGVhcm1hbl9TaGFubm9uX1NDRkEkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fU2hhbm5vbl9TQ0ZBJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDUpCgpjb3JyX3NwZWFybWFuX1NoYW5ub25fU0NGQSRwLmFkanVzdGVkX0ZVIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fU2hhbm5vbl9TQ0ZBJHAudmFsdWVfRlUsIG1ldGhvZCA9ICJCSCIsIG4gPSA1KQoKCmNvcnJfc2lnX1NoYW5ub25fU0NGQSA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9TaGFubm9uX1NDRkEsIHAuYWRqdXN0ZWQgPCAwLjA1IHwgcC5hZGp1c3RlZF9QUkUgPCAwLjUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjUgfCBwLmFkanVzdGVkX0ZVIDwgMC41KQoKd3JpdGUudGFibGUoY29ycl9zaWdfU2hhbm5vbl9TQ0ZBLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL1NDRkEvU0NGQSBhbmFseXNlL1NDRkEgVGFiZWxsZS9TQ0ZBLlNoYW5ub24udHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgotPiBubyBTQ0ZBIGhhcyBzaWduZmljaWNhbnQgcC12YWx1ZSAKIEFjZXRhdGUgaGFzIHRoZSBiZXN0IHAtdmFsdWUgd2l0aCAwLjA2IDwgMC4wNQogClBsb3QgS29ycmVsYXRpb24gQWNldGF0L1RvdGFsIHNjZmEgdW5kIFNoYW5ub24KIApgYGB7cn0KZ2dwbG90KFNDRkFfc3Rvb2wsIGFlcyh4PUFjZXRhdGUsIHk9U2hhbm5vbikpICsgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsKc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCmdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0FjZXRhdGUgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKwp5bGFiKCdTaGFubm9uLUluZGV4JykKCmdncGxvdChTQ0ZBX3N0b29sLCBhZXMoeD1Ub3RhbC5TQ0ZBLCB5PVNoYW5ub24pKSArIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignVG90YWwgU0NGQSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArCiAgeWxhYignU2hhbm5vbi1JbmRleCcpCgpTQ0ZBX3N0b29sIDwtIHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbCwgIVRpbWU9PSAnRk9MTE9XLVVQJykpCgpnZ3NjYXR0ZXIoU0NGQV9zdG9vbF9wYWlyc19QUCwgeD0nQWNldGF0ZScsIHk9J1NoYW5ub24nLCBjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJyksIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQWNldGF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKSArCiAgZmFjZXRfd3JhcCh+VGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1BPU1QnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKZ2dzY2F0dGVyKFNDRkFfc3Rvb2wsIHg9J1RvdGFsLlNDRkEnLCB5PSdTaGFubm9uJywgY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIApjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoMCwgNykseGxhYj0gJ1RvdGFsIFNDRkEgQ29uY2VudHJhdGlvbiBbwrVtb2wvZyBEV10nLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKSsgCmZhY2V0X3dyYXAoflRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkKYGBgCiAKS29ycmVsYXRpb25zYW5hbHlzZW4gendpc2NoZW4gU0NGQSB1bmQgU2ltcHNvbgpFcnN0ZWxsZW4gdm9uIE1hdHJpeCB1bmQgTG9vcCwgZmlsdGVybiBmdWVyIFNpZ25pZmlrYW56CgpgYGB7cn0KY29ycl9zcGVhcm1hbl9TaW1wc29uX1NDRkEgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gdW5pcXVlKGNvcnJfY29sbmFtZXNfU0NGQSkpIHsKICAKdG1wIDwtIGZpbHRlcihTQ0ZBX3N0b29sLCAhaXMubmEoaSkpCgp4ID0gYXMubWF0cml4KGFzLmRhdGEuZnJhbWUobGFwcGx5KHRtcFssaV0sIGFzLm51bWVyaWMpKSkKCnkgPSB0KGFzLm1hdHJpeCh0bXAkU2ltcHNvbikpCiAKdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAKcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKIAp6ID0gYXMubWF0cml4KGFzLmRhdGEuZnJhbWUobGFwcGx5KHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldLGFzLm51bWVyaWMpKSkKICAKdyA9IHQoYXMubWF0cml4IChzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJFNpbXBzb24pKQogIAp0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCgpyaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCnBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKCnIgPSBhcy5tYXRyaXgoYXMuZGF0YS5mcmFtZShsYXBwbHkoc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldLGFzLm51bWVyaWMpKSkKICAKcyA9IHQoYXMubWF0cml4KHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFNpbXBzb24pKQogIAp0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIApyaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCgphID0gYXMubWF0cml4KGFzLmRhdGEuZnJhbWUobGFwcGx5KHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJGT0xMT1ctVVAiKSlbLGldLGFzLm51bWVyaWMpKSkKICAKYiA9IHQoYXMubWF0cml4KHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJGT0xMT1ctVVAiKSkkU2ltcHNvbikpCiAgCnRtcF9jb3JyX3NwZWFybWFuX0ZVIDwtIGNvci50ZXN0KGEsIGIsIG1ldGhvZD0ic3BlYXJtYW4iKQogIApyaG9fRlUgPSB0bXBfY29ycl9zcGVhcm1hbl9GVSRlc3RpbWF0ZQogIApwX0ZVID0gdG1wX2NvcnJfc3BlYXJtYW5fRlUkcC52YWx1ZQoKbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9TaW1wc29uX1NDRkEpKzEKCmNvcnJfc3BlYXJtYW5fU2ltcHNvbl9TQ0ZBW25yb3csIkRpdiJdID0gIlNpbXBzb24iCgpjb3JyX3NwZWFybWFuX1NpbXBzb25fU0NGQVtucm93LCAiY29sdW1uIl0gPSBpCgpjb3JyX3NwZWFybWFuX1NpbXBzb25fU0NGQVtucm93LCAicmhvIl0gPSByaG8KCmNvcnJfc3BlYXJtYW5fU2ltcHNvbl9TQ0ZBW25yb3csICJwLnZhbHVlIl0gPSBwCgpjb3JyX3NwZWFybWFuX1NpbXBzb25fU0NGQVtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQoKY29ycl9zcGVhcm1hbl9TaW1wc29uX1NDRkFbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQoKY29ycl9zcGVhcm1hbl9TaW1wc29uX1NDRkFbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAoKY29ycl9zcGVhcm1hbl9TaW1wc29uX1NDRkFbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCgpjb3JyX3NwZWFybWFuX1NpbXBzb25fU0NGQVtucm93LCAicmhvX0ZVIl0gPSByaG9fRlUKCmNvcnJfc3BlYXJtYW5fU2ltcHNvbl9TQ0ZBW25yb3csICJwLnZhbHVlX0ZVIl0gPSBwX0ZVCgp9Cgpjb3JyX3NwZWFybWFuX1NpbXBzb25fU0NGQSRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fU2ltcHNvbl9TQ0ZBJHAudmFsdWUsbWV0aG9kID0gIkJIIiwgbiA9IDUpCgpjb3JyX3NwZWFybWFuX1NpbXBzb25fU0NGQSRwLmFkanVzdGVkX1BSRSA8LXAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fU2ltcHNvbl9TQ0ZBJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gNSkKCmNvcnJfc3BlYXJtYW5fU2ltcHNvbl9TQ0ZBJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1NpbXBzb25fU0NGQSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSA1KQoKY29ycl9zcGVhcm1hbl9TaW1wc29uX1NDRkEkcC5hZGp1c3RlZF9GVSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1NpbXBzb25fU0NGQSRwLnZhbHVlX0ZVLCBtZXRob2QgPSAiQkgiLCBuID0gNSkKCgpjb3JyX3NpZ19TaW1wc29uX1NDRkEgPC0gZmlsdGVyKGNvcnJfc3BlYXJtYW5fU2ltcHNvbl9TQ0ZBLCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC41IHwgcC5hZGp1c3RlZF9QT1NUIDwgMC41IHwgcC5hZGp1c3RlZF9GVSA8IDAuNSkKCndyaXRlLnRhYmxlKGNvcnJfc2lnX1NpbXBzb25fU0NGQSwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9TQ0ZBL1NDRkEgYW5hbHlzZS9TQ0ZBIFRhYmVsbGUvU0NGQS5TaW1wc29uLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmBgYApubyBtZXRhZGF0YSBoYXMgc2lnbmlmaWNhbnQgcC12YWx1ZQpQcm9waW9uYXQgaGFzIGxvd2VzdCBwLXZhbHVlIDAuMTAgPiAwLjA1CgpQbG90IG1ldGFkYXRhIGZ1ZXIgUHJvcGlvbmF0ZS9Ub3RhbCBzY2ZhIHVuZCBTaW1wc29uCgpgYGB7cn0KZ2dwbG90KFNDRkFfc3Rvb2wsIGFlcyh4PVByb3Bpb25hdGUsIHk9U2ltcHNvbikpICsgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpKwogc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignUHJvcGlvbmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArCiB5bGFiKCdTaW1wc29uLUluZGV4JykKCmdncGxvdChTQ0ZBX3N0b29sLCBhZXMoeD1Ub3RhbC5TQ0ZBLCB5PVNpbXBzb24pKSArIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdUb3RhbCBTQ0ZBIENvbmNlbnRyYXRpb24gW21nL21sXScpICsKICB5bGFiKCdTaW1wc29uLUluZGV4JykKCmdnc2NhdHRlcihTQ0ZBX3N0b29sLCB4PSdQcm9waW9uYXRlJywgeT0nU2ltcHNvbicsIGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSwKYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZj0gVFJVRSwgY29yLmNvZWYuY29vcmQgPSBjKDAsMC45OTgpLApjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1Byb3Bpb25hdGUgQ29uY2VudHJhdGlvbiBbbWcvbWxdJywgeWxhYiA9ICdTaW1wc29uLUluZGV4JykgKyAKZmFjZXRfd3JhcCh+VGltZSkKCmdnc2NhdHRlcihTQ0ZBX3N0b29sLCB4PSdUb3RhbC5TQ0ZBJywgeT0nU2ltcHNvbicsIGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSwKYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZj0gVFJVRSwgY29yLmNvZWYuY29vcmQgPSBjKDAsMC45OTgpLApjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1RvdGFsIFNDRkEgQ29uY2VudHJhdGlvbiBbbWcvbWxdJywgeWxhYiA9ICdTaW1wc29uLUluZGV4JykgKyAKZmFjZXRfd3JhcCh+VGltZSkKCmdnc2NhdHRlcihTQ0ZBX3N0b29sLCB4PSdUb3RhbC5TQ0ZBJywgeT0nU2ltcHNvbicsCiAgICAgICAgICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIGNvci5jb2VmPSBUUlVFLCBjb3IuY29lZi5jb29yZCA9IGMoMCwwLjk5OCksCiAgICAgICAgICBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1RvdGFsIFNDRkEgQ29uY2VudHJhdGlvbiBbwrVtb2wvZ10nLCB5bGFiID0gJ1NpbXBzb24tSW5kZXgnKSAKYGBgCgpEYXRlbiBzaWNoZXJuCgpgYGB7cn0KY29ycl9hcGhhZGl2X1NDRkEgPC0gZGF0YV9mcmFtZSgpCgpjb3JyX2FwaGFkaXZfU0NGQSA8LWJpbmRfcm93cyhjb3JyX3NwZWFybWFuX1NoYW5ub25fU0NGQSxjb3JyX3NwZWFybWFuX1NpbXBzb25fU0NGQSkKCndyaXRlLnRhYmxlKGNvcnJfYXBoYWRpdl9TQ0ZBLCBmaWxlID0gIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL1NDRkEvU0NGQSBhbmFseXNlL09UVSBTQ0ZBIGFuYWx5c2UvY29ycl9hbHBoYWRpdl9TQ0ZBLnR4dCIsIHNlcD0gIlx0IiwgY29sLm5hbWVzID0gVFJVRSwgcm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClNoYW5ub24gYW5kIFNpbXBzb24tSW5kZXggamUgVGltZSBQb2ludCB1bmQgImhpZ2ggY29uY2VudHJhdGlvbiIgUHJvYmFuZHMgCgpgYGB7cn0KClNDRkFfc3Rvb2xfY29uIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL1NDRkEvU0NGQSBUYWJlbGxlIFBoZW5vdHlwZW4udHh0Iiwgc2VwID0gJ1x0JywgY29tbWVudD0nJyxoZWFkPVQsIHJvdy5uYW1lcyA9IDEpCgpjb21tb24uaWRzLlN0IDwtIGludGVyc2VjdChyb3duYW1lcyhTQ0ZBX3N0b29sX2NvbiksIHJvd25hbWVzKG1hcF9hbHBoYWRpdikpCmNvbW1vbi5pZHMuU3QgPC0gaW50ZXJzZWN0KHJvdy5uYW1lcyhTQ0ZBX3N0b29sX2NvbiksIHJvdy5uYW1lcyhtYXBfYWxwaGFkaXYpKQoKU0NGQV9zdG9vbF9jb24gPC0gU0NGQV9zdG9vbF9jb25bY29tbW9uLmlkcy5TdCxdCgptYXBfYWxwaGFkaXYgPC0gbWFwX2FscGhhZGl2W2NvbW1vbi5pZHMuU3QsXQoKYGBgCgpFcnN0ZWxsZW4gZWluZXIgTGlzdGUgZnVlciBjb21wYXJpc29ucyBpbiBib3hwbG90cwoKYGBge3J9CmNvbXBhcmlzb25fY29uIDwtIGxpc3QoYygiaGlnaCBjb25jZW50cmF0aW9ucyIsICJub3JtYWwgY29uY2VudHJhdGlvbnMiKSkKYGBgCgpXaWxjb3hvbiBUZXN0IHp3aXNjaGVuIFBoYWVub3R5cGVuIHVuZCBTaGFubm9uICsgQm94cGxvdAoKYGBge3J9CnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbF9jb24sIFRpbWUgPT0gIlBSRSIpKSRTaGFubm9uLCBzdWJzZXQoZmlsdGVyKFNDRkFfc3Rvb2xfY29uLCBUaW1lID09ICJQUkUiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGQUxTRSkKCmdncGxvdChzdWJzZXQoZmlsdGVyKFNDRkFfc3Rvb2xfY29uKSksIGFlcyh4PVBoZW5vdHlwZSwgeT1TaGFubm9uKSkgKyB4bGFiKCdQaGVub3R5cGUnKSArIHlsYWIoJ1NoYW5ub24tSW5kZXgnKSsKZ2VvbV9ib3hwbG90KGZpbGwgPSd3aGl0ZXNtb2tlJywgY29sb3IgPSAnYmxhY2snKSArCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAnIHknLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yID0gJ2dyZXkyMicpICsgCiAgZmFjZXRfd3JhcCh+VGltZSkgKwpzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gRiwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoImhpZ2ggY29udmVydGVyIiwgImxvdyBjb252ZXJ0ZXIiKSkpCgpgYGAKCldpbGNveG9uIHRlc3Qgendpc2NoZW4gUGhhZW5vdHlwZW4gdW5kIFNpbXBzb24gKyBCb3hwbG90CgpgYGB7cn0KcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihTQ0ZBX3N0b29sX2NvbiwgVGltZSA9PSAiUFJFIikpJFNpbXBzb24sIHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbF9jb24sIFRpbWUgPT0gIlBSRSIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIoU0NGQV9zdG9vbF9jb24pKSwgYWVzKHg9UGhlbm90eXBlLCB5PVNpbXBzb24pKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignU2ltcHNvbi1JbmRleCcpKyAKICBnZW9tX2JveHBsb3QoZmlsbCA9J3doaXRlc21va2UnLCBjb2xvciA9ICdibGFjaycpICsKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICcgeScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKyAKICBmYWNldF93cmFwKH5UaW1lKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl9jb24sIHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pKQoKYGBgCgoxLjYgUmVsYXRpdmUgQWJ1bmRhbmNlIFNDRkEtQW5hbHlzZQpMYWRlbiwgZmlsdGVybiBmdWVyIGhpZ2ggYWJ1bmRhbnQgdGF4YSB1bmQgc2ljaGVybiBkZXIgTWV0YWRhdGVuIAoKYGBge3J9Ckw2X3JhcmVmaWVkIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL01hcHBpbmdmaWxlXzE2U3JSTkFfQkMyMl9MNi50eHQiLCBzZXA9ICdcdCcsIGNvbW1lbnQ9JycsIGhlYWQ9VCkKCkw2X3JhcmVmaWVkIDwtIGZpbHRlcihMNl9yYXJlZmllZCwgQm9keXNpdGUgPT0gIlN0b29sIikKCnJvdy5uYW1lcyhMNl9yYXJlZmllZCkgPC0gTDZfcmFyZWZpZWQkWC5TYW1wbGVJRAoKTDZfcmFyZWZpZWQgPC0gTDZfcmFyZWZpZWRbLC1jKDE6MTgpXQoKTDZfdGF4YSA8LSBMNl9yYXJlZmllZFssIGNvbFN1bXMoTDZfcmFyZWZpZWQgPiAwLjAxKSA+IDEwXQoKTDZfdGF4YSA8LSBMNl90YXhhICU+JSBzZWxlY3QoLXN0YXJ0c193aXRoKCJVbmFzc2lnbmVkIikpCgpMNl90YXhhPC0gc3dlZXAoTDZfdGF4YSwgMSwgcm93U3VtcyhMNl90YXhhKSwnLycpCgptYXBfS0QgPC0gcmVhZC50YWJsZSgiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvTWFwcGluZ2ZpbGVfMTZTclJOQV9CQzIyLnR4dCIsIHNlcCA9J1x0JywgY29tbWVudD0nJywgaGVhZD1ULApyb3cubmFtZXMgPSAxKQoKTDZfdGF4YSA8LSByb3duYW1lc190b19jb2x1bW4oTDZfdGF4YSwgIlNhbXBsZUlEIikKCm1hcF9LRCA8LSByb3duYW1lc190b19jb2x1bW4obWFwX0tELCAiU2FtcGxlSUQiKQoKTDZfbWV0YWRhdGFfdGF4YSA8LSBtZXJnZShtYXBfS0QsIEw2X3RheGEsIGJ5Lng9YygiU2FtcGxlSUQiKSwgYnkueT1jKCJTYW1wbGVJRCIpKQpMNl9tZXRhZGF0YV90YXhhIDwtIEw2X21ldGFkYXRhX3RheGFbLC1jKDIsMywxMDoxNSldCkw2X21ldGFkYXRhX3RheGEgPC0gTDZfbWV0YWRhdGFfdGF4YVssLWMoOSldCgoKd3JpdGUudGFibGUoTDZfbWV0YWRhdGFfdGF4YSwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9yZWxhdGl2ZSBhYnVuZGFuY2UvTDZfbWV0YWRhdGFfdGF4YV9zdHJpY3Rfc3Rvb2wudHh0Jywgc2VwID0gIlx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKYGBgCgpGaWx0ZXJuIGRlcyBEYXRlbnNhdHplcyBtaXQgZGVyIHJlYWx0aXZlIGFidW5kYW5jZSBuYWNoIGRlbiBaZWl0cHVua3RlbiwgQmVzdGltbXVuZyBkZXIgTWVhbnMgamUgWmVpdHB1bmt0Clp1c2FtbWVuZnVlZ2VuIGRlciBEYXRlbnPDpHR6ZQoKYGBge3J9CnJlbGFiIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3JlbGF0aXZlIGFidW5kYW5jZS9MNl9tZXRhZGF0YV90YXhhX3N0cmljdF9zdG9vbC50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLCBoZWFkPVQpCgpyZWxhYl9QUkUgPC0gZmlsdGVyKHJlbGFiLCBUaW1lID09ICJQUkUiKQoKcmVsYWJfUE9TVCA8LSBmaWx0ZXIocmVsYWIsIFRpbWUgPT0gIlBPU1QiKQoKcmVsYWJfRlUgPC0gZmlsdGVyKHJlbGFiLCBUaW1lID09ICJGT0xMT1ctVVAiKQoKcmVsYWJfbWVhbnNfUFJFIDwtIGFnZ3JlZ2F0ZShyZWxhYl9QUkVbLCAxMDo5MF0sIGxpc3QocmVsYWJfUFJFJFByb2JhbmQpLCBtZWFuKQoKcmVsYWJfbWVhbnNfUFJFWydUaW1lJ10gPSAnUFJFJwoKcmVsYWJfbWVhbnNfUFJFIDwtIHJlbmFtZShyZWxhYl9tZWFuc19QUkUsIFByb2JhbmQ9R3JvdXAuMSkKCnJlbGFiX21lYW5zX1BPU1QgPC0gYWdncmVnYXRlKHJlbGFiX1BPU1RbLCAxMDo5MF0sIGxpc3QocmVsYWJfUE9TVCRQcm9iYW5kKSwgbWVhbikKCnJlbGFiX21lYW5zX1BPU1RbJ1RpbWUnXSA9ICdQT1NUJwoKcmVsYWJfbWVhbnNfUE9TVCA8LSByZW5hbWUocmVsYWJfbWVhbnNfUE9TVCwgUHJvYmFuZD1Hcm91cC4xKQoKcmVsYWJfbWVhbnNfRlUgPC0gYWdncmVnYXRlKHJlbGFiX0ZVWywgMTA6OTBdLCBsaXN0KHJlbGFiX0ZVJFByb2JhbmQpLCBtZWFuKQoKcmVsYWJfbWVhbnNfRlVbJ1RpbWUnXSA9ICdGT0xMT1ctVVAnCgpyZWxhYl9tZWFuc19GVSA8LSByZW5hbWUocmVsYWJfbWVhbnNfRlUsIFByb2JhbmQ9R3JvdXAuMSkKCnJlbGFiX21lYW5zIDwtIGRhdGFfZnJhbWUoKQoKcmVsYWJfbWVhbnMgPC0gYmluZF9yb3dzKHJlbGFiX21lYW5zX1BSRSwgcmVsYWJfbWVhbnNfUE9TVCwgcmVsYWJfbWVhbnNfRlUpCgpyZWxhYl9tZWFucyA8LSByZWxhYl9tZWFuc1ssIGMoMSwgODMsIDI6ODIpXQoKbmNvbChyZWxhYl9tZWFucykKCgp3cml0ZS50YWJsZShyZWxhYl9tZWFucywgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9yZWxhdGl2ZSBhYnVuZGFuY2UvcmVsYWJfbWVhbnNfcGVyX3RpbWVwb2ludC50eHQnLHNlcCA9ICJcdCIsIGNvbC5uYW1lcyA9IFRSVUUsIHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgpVbWJlbmVubmVuIGRlciBTcGFsdGVuCgpgYGB7cn0KcmVsYWJfbWVhbnMgPC0gcmVhZC50YWJsZSgnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvcmVsYXRpdmUgYWJ1bmRhbmNlL3JlbGFiX21lYW5zX3Blcl90aW1lcG9pbnQudHh0Jywgc2VwID0nXHQnLCBjb21tZW50PScnLCBoZWFkPVQpCgpyZWxhYl9tZWFuc19tZWx0IDwtIG1lbHQocmVsYWJfbWVhbnMsIGlkPWMoJ1Byb2JhbmQnLCAnVGltZScpKQoKcmVsYWJfbWVhbnNfbWVsdCA8LSByZW5hbWUocmVsYWJfbWVhbnNfbWVsdCwgVGF4YT12YXJpYWJsZSkKCnJlbGFiX21lYW5zX21lbHQgPC0gcmVuYW1lKHJlbGFiX21lYW5zX21lbHQsIFJlbGF0aXZlX0FidW5kYW5jZT12YWx1ZSkKYGBgCgpTdWJzZXQgcGh5bHVtIHVuZCBnZW51cyBsZXZlbCwgc2ljaGVybiBkZXIgRGF0ZW4KCmBgYHtyfQpyZWxhYl9waHlsdW0gPC0gc3Vic2V0KHJlbGFiX21lYW5zX21lbHQsICFncmVwbCgiZ19ffGZfX3xvX198Y19fIiwgcmVsYWJfbWVhbnNfbWVsdCRUYXhhKSkKCnJlbGFiX3BoeWx1bSA8LSBzdWJzZXQocmVsYWJfcGh5bHVtLCAhZ3JlcGwoImtfX0FyY2hhZWEiLCByZWxhYl9waHlsdW0kVGF4YSkpCgpyZWxhYl9waHlsdW0kVGltZSA8LSBmYWN0b3IocmVsYWJfcGh5bHVtJFRpbWUsIGxldmVscz1jKCdQUkUnLCdQT1NUJywnRk9MTE9XLVVQJykpCgpyZWxhYl9waHlsdW1fc3ByZWFkIDwtIHNwcmVhZChyZWxhYl9waHlsdW0sIFRheGEsIFJlbGF0aXZlX0FidW5kYW5jZSwgc2VwID0gTlVMTCkKCnJlbGFiX2dlbnVzIDwtIHN1YnNldChyZWxhYl9tZWFuc19tZWx0LCBncmVwbCgiZ19fIiwgcmVsYWJfbWVhbnNfbWVsdCRUYXhhKSkKCnJlbGFiX2dlbnVzIDwtIHN1YnNldChyZWxhYl9nZW51cywgIWdyZXBsKCJrX19BcmNoYWVhIiwgcmVsYWJfZ2VudXMkVGF4YSkpCgpyZWxhYl9nZW51cyRUaW1lIDwtIGZhY3RvcihyZWxhYl9nZW51cyRUaW1lLCBsZXZlbHMgPSBjKCdQUkUnLCdQT1NUJywnRk9MTE9XLVVQJykpCgpyZWxhYl9nZW51c19zcHJlYWQgPC0gc3ByZWFkKHJlbGFiX2dlbnVzLCBUYXhhLCBSZWxhdGl2ZV9BYnVuZGFuY2UsIHNlcCA9IE5VTEwpCgogd3JpdGUudGFibGUocmVsYWJfcGh5bHVtX3NwcmVhZCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9yZWxhdGl2ZSBhYnVuZGFuY2UvcmVsYWJfcGh5bHVtLnR4dCcsIHNlcD0gIlx0IiwgY29sLm5hbWVzID0gVFJVRSwgcm93Lm5hbWVzID0gRkFMU0UpCgp3cml0ZS50YWJsZShyZWxhYl9nZW51c19zcHJlYWQsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvcmVsYXRpdmUgYWJ1bmRhbmNlL3JlbGFiX2dlbnVzLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSwgcm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKVGVzdGVuIGRlciBUYXhhIGF1ZiBOb3JtYWx2ZXJ0ZWlsdW5nLCBQaHlsdW0gdW5kIEdlbnVzCkFuc2NobGllw59lbmRlcyBGaWx0ZXJuIG5hY2ggTm9ybWFsdmVydGVpbHVuZwoKYGBge3J9CnRlc3Rfbm9ybWRpc3RfcGh5bHVtIDwtIGRhdGEuZnJhbWUoKQoKcGh5bHVtX2NvbG5hbWVzIDwtIGNvbG5hbWVzKHJlbGFiX3BoeWx1bV9zcHJlYWRbLCBjKDM6OCldKQoKZm9yIChpIGluIHBoeWx1bV9jb2xuYW1lcykgewogIAogIGZpdCA8LSBzaGFwaXJvLnRlc3QocmVsYWJfcGh5bHVtX3NwcmVhZFssaV0pCiAgCiAgcCA9IGZpdCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3codGVzdF9ub3JtZGlzdF9waHlsdW0pKzEKICAKICB0ZXN0X25vcm1kaXN0X3BoeWx1bVtucm93LCAicC52YWx1ZSJdID0gcAogIAogIHRlc3Rfbm9ybWRpc3RfcGh5bHVtW25yb3csICJjb2x1bW4iXSA9IGkKICAKfQoKdGVzdF9ub3JtZGlzdF9nZW51cyA8LSBkYXRhX2ZyYW1lKCkKCmdlbnVzX2NvbG5hbWVzIDwtY29sbmFtZXMocmVsYWJfZ2VudXNfc3ByZWFkWywgYygzOjMxKV0pCgpmb3IgKGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAKICBmaXQgPC0gc2hhcGlyby50ZXN0KHJlbGFiX2dlbnVzX3NwcmVhZFssaV0pCiAgCiAgcCA9IGZpdCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3codGVzdF9ub3JtZGlzdF9nZW51cykrMQogIAogIHRlc3Rfbm9ybWRpc3RfZ2VudXNbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICB0ZXN0X25vcm1kaXN0X2dlbnVzW25yb3csICJjb2x1bW4iXSA9IGkKICAKfQoKCm5vcm1kaXN0X3BoeWx1bSA8LSBmaWx0ZXIodGVzdF9ub3JtZGlzdF9waHlsdW0sIHAudmFsdWUgPiAwLjA1KQpub3JtZGlzdF9nZW51cyA8LSBmaWx0ZXIodGVzdF9ub3JtZGlzdF9nZW51cywgcC52YWx1ZSA+IDAuMDUpCmBgYAotPiBudXIgQmFjdGVyb2lkZXRlcywgQmFjdGVyb2lkZXMsIERvcmVhLCBCbGF1dGlhLCBGYWVjYWxpYmFjdGVyaXVtIG5vcm1hbHZlcnRlaWx0CgpLb3JyZWxhdGlvbnNhbmFseXNlbiBtaXQgU0NGQQoKU3luY2hvbmlzaWVyZW4gZGVyIE1ldGFkYXRlbgoKYGBge3J9CnJlbGFiX3BoeWx1bV9JRCA8LSByZWxhYl9waHlsdW1fc3ByZWFkCgpyZWxhYl9waHlsdW1fSUQgPC0gbXV0YXRlKHJlbGFiX3BoeWx1bV9JRCwgU2FtcGxlSUQgPSBwYXN0ZShQcm9iYW5kLCBUaW1lLHNlcD0iLiIpKQoKcm93Lm5hbWVzKHJlbGFiX3BoeWx1bV9JRCkgPC0gcmVsYWJfcGh5bHVtX0lEJFNhbXBsZUlECgpyZWxhYl9nZW51c19JRCA8LSByZWxhYl9nZW51c19zcHJlYWQKCnJlbGFiX2dlbnVzX0lEIDwtIG11dGF0ZShyZWxhYl9nZW51c19JRCwgU2FtcGxlSUQgPSBwYXN0ZShQcm9iYW5kLCBUaW1lLCBzZXAgPSIuIikpCgpyb3cubmFtZXMocmVsYWJfZ2VudXNfSUQpIDwtIHJlbGFiX2dlbnVzX0lEJFNhbXBsZUlECgpTQ0ZBX3N0b29sIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG93bmxvYWRzL1NDRkFfc3Rvb2wgdG90YWwgU0NGQS50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLGhlYWQ9VCwgcm93Lm5hbWVzID0gMSkKClZpZXcoU0NGQV9zdG9vbCkKClNDRkFfc3Rvb2w8LSBhZGQucm93bmFtZXMoU0NGQV9zdG9vbCwgIlNhbXBsZUlEIikKClNDRkFfc3Rvb2wkVGltZSA8LWZhY3RvcihTQ0ZBX3N0b29sJFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIiwgIkZPTExPV1VQIikpCgpTQ0ZBX3N0b29sWzEsM108LSAiUFJFIgoKU0NGQV9zdG9vbFsxLDRdPC0gIk9VMSIKClNDRkFfc3Rvb2wgPC0gbXV0YXRlKFNDRkFfc3Rvb2wsIFNhbXBsZUlEMSA9IHBhc3RlKFByb2JhbmQsIFRpbWUsIHNlcCA9ICIuIikpCgpyb3cubmFtZXMoU0NGQV9zdG9vbCkgPC0gU0NGQV9zdG9vbCRTYW1wbGVJRDEKCmNvbW1vbi5pZHMucmVsYWIgPC0gaW50ZXJzZWN0KHJvd25hbWVzKFNDRkFfc3Rvb2wpLCByb3duYW1lcyhyZWxhYl9waHlsdW1fSUQpKQoKU0NGQV9zdG9vbCA8LSBTQ0ZBX3N0b29sW2NvbW1vbi5pZHMucmVsYWIsXQoKcmVsYWJfcGh5bHVtX0lEIDwtIHJlbGFiX3BoeWx1bV9JRFtjb21tb24uaWRzLnJlbGFiLF0KCnJlbGFiX2dlbnVzX0lEIDwtIHJlbGFiX2dlbnVzX0lEW2NvbW1vbi5pZHMucmVsYWIsXQoKd3JpdGUudGFibGUoU0NGQV9zdG9vbCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9TQ0ZBL1NDRkFfc3Rvb2xfdG90YWwudHh0Jywgc2VwPSAiXHQiLCBjb2wubmFtZXMgPSBUUlVFLCByb3cubmFtZXMgPSBGQUxTRSkKCmBgYAoKRXJzdGVsbGVuIGVpbmVyIE1hdHJpeCB6dW0gdGVzdGVuIGRlciBnZXd1ZW5zY2h0ZW4gRGF0ZW4sIGhpbnp1ZnVlZ2VuIHZvbiBlaW5lbSBQc2V1ZG9jb3VudCAwLjAwMDAxIHVuZCBsb2ctVHJhbnNmb3JtYXRpb24KCmBgYHtyfQpwaHlsdW1fY29sbmFtZXMgPC0gY29sbmFtZXMocmVsYWJfcGh5bHVtX3NwcmVhZFssIGMoMzo4KV0pCgpyZWxhYl9waHlsdW1fSURfbG9nIDwtIHJlbGFiX3BoeWx1bV9JRFssYygzOjgpXSArIDAuMQoKcmVsYWJfcGh5bHVtX0lEX2xvZyA8LSBsb2cxMChyZWxhYl9waHlsdW1fSURfbG9nKQoKcGh5bHVtX1NDRkEgPC0gY2JpbmQocmVsYWJfcGh5bHVtX0lEX2xvZywgU0NGQV9zdG9vbFssIGMoMSwgMzo1LCA3OjExKV0pCgpwaHlsdW1fU0NGQSRUaW1lIDwtIGZhY3RvcihwaHlsdW1fU0NGQSRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQpgYGAKCkxvb3AgS29ycmVsYXRpb25zYW5hbHlzZSBBY2V0YXQgdW5kIFBoeWx1bS1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX3BoeWx1bV9BYyA8LSBmaWx0ZXIocGh5bHVtX1NDRkEsICFpcy5uYShBY2V0YXRlKSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0FjIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX0FjLCAhaXMubmEoaSkpCiAgCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJEFjZXRhdGUKICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCgogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJEFjZXRhdGUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKCiByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJEFjZXRhdGUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fQWMpKzEKCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fQWNbbnJvdywiU0NGQSJdIDwtICJBY2V0YXRlIgogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0FjW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9BY1tucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0FjW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0FjW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9BY1tucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0FjW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0FjW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fQWMkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9BYyRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpIAoKY29ycl9zcGVhcm1hbl9QaHlsdW1fQWMkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fQWMkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0FjJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9BYyRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc2lnX1BoeWx1bV9BYyA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9QaHlsdW1fQWMsIHAuYWRqdXN0ZWQgPCAwLjA1IHwgcC5hZGp1c3RlZF9QUkUgPCAwLjA1IHwgcC5hZGp1c3RlZF9QT1NUIDwgMC4wNSkKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX0FjLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL1NDRkEvU0NGQSBhbmFseXNlL1NDRkEgVGFiZWxsZS9QaHlsdW0uQWMudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgpQbG90dGVuIHZvbiBBY2V0YXQgdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9CnBoeWx1bV9TQ0ZBJFRpbWUgPC0gZmFjdG9yKHBoeWx1bV9TQ0ZBJFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIikpCmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcywgeD1BY2V0YXRlKSkgKyAKZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCmdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0FjZXRhdGUgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCiAKCmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEsIHg9QWNldGF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignQWNldGF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcywgeD1BY2V0YXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdBY2V0YXRlIENvbmNlbnRyYXRpb24gW8K1bW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSwgc2NhbGVzID0gImZyZWVfeCIpCgpnZ3NjYXR0ZXIocGh5bHVtX1NDRkEsIHg9J0FjZXRhdGUnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDAsIC0wLjgpLCB4bGFiPSAnQWNldGF0ZSBDb25jZW50cmF0aW9uIFvCtW1vbC9nIERXXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fU0NGQSwgeD0nQWNldGF0ZScsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoMCwgLTAuOCksIHhsYWI9ICdBY2V0YXRlIENvbmNlbnRyYXRpb24gW8K1bW9sL2cgRFddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMnKSsKCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEsIHg9QWNldGF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignQWNldGF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVGVuZXJpY3V0ZXMsIHg9QWNldGF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignQWNldGF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLCB4PUFjZXRhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0FjZXRhdGUgQ29uY2VudHJhdGlvbiBbwrVtb2wvZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVmVycnVjb21pY3JvYmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3NjYXR0ZXIocGh5bHVtX1NDRkEsIHg9J0FjZXRhdGUnLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoMCwgLTAuOCksIHhsYWI9ICdBY2V0YXRlIENvbmNlbnRyYXRpb24gW8K1bW9sL2cgRFddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX1NDRkEsIHg9J0FjZXRhdGUnLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoMCwgLTAuOCksIHhsYWI9ICdBY2V0YXRlIENvbmNlbnRyYXRpb24gW8K1bW9sL2cgRFddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYScpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmBgYAoKTG9vcCBLb3JyZWxhdGlvbnNhbmFseXNlIFByb3Bpb25hdCB1bmQgUGh5bHVtLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX1ByIDwtIGZpbHRlcihwaHlsdW1fU0NGQSwgIWlzLm5hKFByb3Bpb25hdGUpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fUHIgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9waHlsdW1fUHIsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkUHJvcGlvbmF0ZQoKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCgogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJFByb3Bpb25hdGUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRQcm9waW9uYXRlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fUHIpKzEKCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fUHJbbnJvdywiU0NGQSJdIDwtICJQcm9waW9uYXRlIgogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1ByW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9Qcltucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1ByW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1ByW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9Qcltucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1ByW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1ByW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fUHIkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9QciRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpIApjb3JyX3NwZWFybWFuX1BoeWx1bV9QciRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9QciRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQpjb3JyX3NwZWFybWFuX1BoeWx1bV9QciRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fUHIkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NpZ19QaHlsdW1fUHIgPC0gZmlsdGVyKGNvcnJfc3BlYXJtYW5fUGh5bHVtX1ByLCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9QciwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9TQ0ZBL1NDRkEgYW5hbHlzZS9TQ0ZBIFRhYmVsbGUvUGh5bHVtLlByLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmBgYAoKUGxvdHRlbiBQcm9waW9uYXQgdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9CmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcywgeD1Qcm9waW9uYXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdQcm9waW9uYXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QocGh5bHVtX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLCB4PVByb3Bpb25hdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ1Byb3Bpb25hdGUgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QocGh5bHVtX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMsIHg9UHJvcGlvbmF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignUHJvcGlvbmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dwbG90KHBoeWx1bV9TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYSwgeD1Qcm9waW9uYXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdQcm9waW9uYXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dwbG90KHBoeWx1bV9TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcywgeD1Qcm9waW9uYXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdQcm9waW9uYXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dwbG90KHBoeWx1bV9TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEsIHg9UHJvcGlvbmF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignUHJvcGlvbmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVmVycnVjb21pY3JvYmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpgYGAKCkxvb3AgQnV0eXJhdCB1bmQgUGh5bHVtLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX0J1IDwtIGZpbHRlcihwaHlsdW1fU0NGQSwgIWlzLm5hKEJ1dHlyYXRlKSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0J1IDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewoKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9CdSwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRCdXR5cmF0ZQoKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQoKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRCdXR5cmF0ZQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQoKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJEJ1dHlyYXRlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9CdSkrMQoKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9CdVtucm93LCJTQ0ZBIl0gPC0gIkJ1dHlyYXRlIgogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0J1W25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9CdVtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0J1W25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0J1W25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9CdVtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0J1W25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0J1W25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fQnUkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9CdSRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpIAoKY29ycl9zcGVhcm1hbl9QaHlsdW1fQnUkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fQnUkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0J1JHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9CdSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc2lnX1BoeWx1bV9CdSA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9QaHlsdW1fQnUsIHAuYWRqdXN0ZWQgPCAwLjA1IHwgcC5hZGp1c3RlZF9QUkUgPCAwLjA1IHwgcC5hZGp1c3RlZF9QT1NUIDwgMC4wNSkKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX0J1LCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL1NDRkEvU0NGQSBhbmFseXNlL1NDRkEgVGFiZWxsZS9QaHlsdW0uQnUudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgpQbG90dGVuIEJ1dHlyYXRlIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QocGh5bHVtX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMsIHg9QnV0eXJhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0J1dHlyYXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QocGh5bHVtX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLCB4PUJ1dHlyYXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdCdXR5cmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcywgeD1CdXR5cmF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignQnV0eXJhdGUgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEsIHg9QnV0eXJhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0J1dHlyYXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsgCiAgc2NhbGVfZmFjZXRfd3JhcF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKZ2dwbG90KHBoeWx1bV9TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcywgeD1CdXR5cmF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignQnV0eXJhdGUgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1RlbmVyaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QocGh5bHVtX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSwgeD1CdXR5cmF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignQnV0eXJhdGUgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKYGBgCgpMb29wIGZ1ZXIgSXNvYnV0eXJhdCB1bmQgUGh5bHVtLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX0lCIDwtIGZpbHRlcihwaHlsdW1fU0NGQSwgIWlzLm5hKElzby5CdXR5cmF0ZSkpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9JQiA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBwaHlsdW1fY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9JQiwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRJc28uQnV0eXJhdGUKCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCgogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkSXNvLkJ1dHlyYXRlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCgogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkSXNvLkJ1dHlyYXRlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fSUIpKzEKCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fSUJbbnJvdywiU0NGQSJdIDwtICJJc28uQnV0eXJhdGUiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fSUJbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0lCW25yb3csICJwLnZhbHVlIl0gPSBwCgogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0lCW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0lCW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9JQltucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0lCW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0lCW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fSUIkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9JQiRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpIAoKY29ycl9zcGVhcm1hbl9QaHlsdW1fSUIkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fSUIkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0lCJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9JQiRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc2lnX1BoeWx1bV9JQiA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9QaHlsdW1fSUIsIHAuYWRqdXN0ZWQgPCAwLjA1IHwgcC5hZGp1c3RlZF9QUkUgPCAwLjA1IHwgcC5hZGp1c3RlZF9QT1NUIDwgMC4wNSkKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX0lCLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL1NDRkEvU0NGQSBhbmFseXNlL1NDRkEgVGFiZWxsZS9QaHlsdW0uSUIudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgpQbG90dGVuIElzb2J1dHlyYXQgdW5kIFBoeWx1bS1sZXZlbAoKYGBge3J9CmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcywgeD1Jc28uQnV0eXJhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0lzby5CdXR5cmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fRmlybWljdXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dwbG90KHBoeWx1bV9TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYSwgeD1Jc28uQnV0eXJhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0lzby5CdXR5cmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcywgeD1Jc28uQnV0eXJhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0lzby5CdXR5cmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dwbG90KHBoeWx1bV9TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYSwgeD1Jc28uQnV0eXJhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0lzby5CdXR5cmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVGVuZXJpY3V0ZXMsIHg9SXNvLkJ1dHlyYXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdJc28uQnV0eXJhdGUgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1RlbmVyaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QocGh5bHVtX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSwgeD1Jc28uQnV0eXJhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0lzby5CdXR5cmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVmVycnVjb21pY3JvYmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCmBgYAoKTG9vcCBUb3RhbCBTQ0ZBIHVuZCBQaHlsdW0tbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9waHlsdW1fVFMgPC0gZmlsdGVyKHBoeWx1bV9TQ0ZBLCAhaXMubmEoVG90YWwuU0NGQSkpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9UUyA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBwaHlsdW1fY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9UUywgIWlzLm5hKGkpKQogCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJFRvdGFsLlNDRkEKCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCgogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkVG90YWwuU0NGQQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQoKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFRvdGFsLlNDRkEKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQoKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9UUykrMQoKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9UU1tucm93LCJTQ0ZBIl0gPC0gIlRvdGFsLlNDRkEiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fVFNbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1RTW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fVFNbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fVFNbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1RTW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fVFNbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fVFNbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9UUyRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1RTJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkgCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9UUyRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9UUyRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fVFMkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1RTJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zaWdfUGh5bHVtX1RTIDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX1BoeWx1bV9UUywgcC5hZGp1c3RlZCA8IDAuMDUgfCBwLmFkanVzdGVkX1BSRSA8IDAuMDUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjA1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9QaHlsdW1fVFMsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvU0NGQS9TQ0ZBIGFuYWx5c2UvU0NGQSBUYWJlbGxlL1BoeWx1bS5UUy50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gVG90YWwgU0NGQSB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KZ2dwbG90KHBoeWx1bV9TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLCB4PVRvdGFsLlNDRkEpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ1RvdGFsLlNDRkEgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0Zpcm1pY3V0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEsIHg9VG90YWwuU0NGQSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignVG90YWwuU0NGQSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChwaHlsdW1fU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcywgeD1Ub3RhbC5TQ0ZBKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdUb3RhbC5TQ0ZBIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QocGh5bHVtX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLCB4PVRvdGFsLlNDRkEpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ1RvdGFsLlNDRkEgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QocGh5bHVtX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzLCB4PVRvdGFsLlNDRkEpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ1RvdGFsLlNDRkEgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1RlbmVyaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QocGh5bHVtX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSwgeD1Ub3RhbC5TQ0ZBKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdUb3RhbC5TQ0ZBIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKYGBgCgpTaWNoZXJuIGRlciBEYXRlbgoKYGBge3J9CmNvcnJfcGh5bHVtX1NDRkEgPC0gZGF0YV9mcmFtZSgpCgpjb3JyX3BoeWx1bV9TQ0ZBIDwtIGJpbmRfcm93cyhjb3JyX3NwZWFybWFuX1BoeWx1bV9BYyxjb3JyX3NwZWFybWFuX1BoeWx1bV9Qcixjb3JyX3NwZWFybWFuX1BoeWx1bV9CdSwgY29ycl9zcGVhcm1hbl9QaHlsdW1fSUIsIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1RTKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCndyaXRlLnRhYmxlKGNvcnJfcGh5bHVtX1NDRkEsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvcmVsYXRpdmUgYWJ1bmRhbmNlL2NvcnJfcGh5bHVtX1NDRkFfYWxsX1BSRV9QT1NULnR4dCcsc2VwID0gIlx0IiwgY29sLm5hbWVzID0gVFJVRSwgcm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKCkFuYWx5c2VuIG1pdCBHZW51cy1MZXZlbAoKRXJzdGVsbGVuIHVuZCBmaWx0ZXJuIGRlciBNYXRyaXgsIExvZy1UcmFuc2Zvcm1hdGlvbiB1bmQgaGluenVmdWVnZW4gdm9uIFBzZXVkb2NvdW50IDAuMDAwMDEKCmBgYHtyfQogZ2VudXNfY29sbmFtZXMgPC0gY29sbmFtZXMocmVsYWJfZ2VudXNfc3ByZWFkWywgYygzOjMxKV0pCgpyZWxhYl9nZW51c19JRF9sb2cgPC0gcmVsYWJfZ2VudXNfSURbLGMoMzozMSldICsgMC4wMDAwMQoKcmVsYWJfZ2VudXNfSURfbG9nIDwtIGxvZzEwKHJlbGFiX2dlbnVzX0lEX2xvZykKCmdlbnVzX1NDRkEgPC0gY2JpbmQocmVsYWJfZ2VudXNfSURfbG9nLCBTQ0ZBX3N0b29sWywgYygxOjEwKV0pCgpgYGAKCkxvb3AgQWNldGF0ZSB1bmQgR2VudXMtTGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9nZW51c19BYyA8LSBmaWx0ZXIoZ2VudXNfU0NGQSwgIWlzLm5hKEFjZXRhdGUpKQoKY29ycl9zcGVhcm1hbl9nZW51c19BYyA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBnZW51c19jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfZ2VudXNfQWMsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkQWNldGF0ZQogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRBY2V0YXRlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRBY2V0YXRlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX2dlbnVzX0FjKSsxCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19BY1tucm93LCJTQ0ZBIl0gPSAiQWNldGF0ZSIKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX0FjW25yb3csICJHZW51cyJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfQWNbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX0FjW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfQWNbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfQWNbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX0FjW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfQWNbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX2dlbnVzX0FjJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19BYyRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX0FjJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfQWMkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfQWMkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfQWMkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NpZ19nZW51c19BYyA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9nZW51c19BYywgcC5hZGp1c3RlZCA8IDAuMDUgfCBwLmFkanVzdGVkX1BSRSA8IDAuMDUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjA1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9nZW51c19BYywgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9TQ0ZBL1NDRkEgYW5hbHlzZS9TQ0ZBIFRhYmVsbGUvR2VudXMuQWMudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgpQbG90dGVuIEFjZXRhdGUgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KZ2dwbG90KGdlbnVzX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEsIHg9QWNldGF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignQWNldGF0ZSBDb25jZW50cmF0aW9uIFvCtW1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdnc2NhdHRlcihnZW51c19TQ0ZBLCB4PSdBY2V0YXRlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLGNvci5jb2VmLmNvb3JkID0gYyg1MCwgLTIpLCB4bGFiPSAnQWNldGF0ZSBDb25jZW50cmF0aW9uIFvCtW1vbC9nIERXXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKGdlbnVzX1NDRkEsIHg9J0FjZXRhdGUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDUwLCAtMiksIHhsYWI9ICdBY2V0YXRlIENvbmNlbnRyYXRpb24gW8K1bW9sL2cgRFddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpK3RoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bSwgeD1BY2V0YXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdBY2V0YXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CaWZpZG9iYWN0ZXJpdW0pJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChnZW51c19TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19Db3Jpb2JhY3RlcmlpYS5vX19Db3Jpb2JhY3RlcmlhbGVzLmZfX0NvcmlvYmFjdGVyaWFjZWFlLmdfX0NvbGxpbnNlbGxhLCB4PUFjZXRhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0FjZXRhdGUgQ29uY2VudHJhdGlvbiBbbm1vbC9tZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29sbGluc2VsbGEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChnZW51c19TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0VyeXNpcGVsb3RyaWNoaS5vX19FcnlzaXBlbG90cmljaGFsZXMuZl9fRXJ5c2lwZWxvdHJpY2hhY2VhZS5nX18sIHg9QWNldGF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignQWNldGF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZl9fRXJ5c2lwZWxvdHJpY2hhY2VhZSknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dwbG90KGdlbnVzX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19SaWtlbmVsbGFjZWFlLmdfXywgeD1BY2V0YXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdBY2V0YXRlIENvbmNlbnRyYXRpb24gW8K1bW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGZfX1Jpa2VuZWxsYWNlYWUpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChnZW51c19TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bSwgeD1BY2V0YXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdBY2V0YXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtICknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dwbG90KGdlbnVzX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhLCB4PUFjZXRhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0FjZXRhdGUgQ29uY2VudHJhdGlvbiBbwrVtb2wvZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQWtrZXJtYW5zaWEgKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3NjYXR0ZXIoZ2VudXNfU0NGQSwgeD0nQWNldGF0ZScsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDUwLCAtMS4xKSwgeGxhYj0gJ0FjZXRhdGUgQ29uY2VudHJhdGlvbiBbwrVtb2wvZyBEV10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQWtrZXJtYW5zaWEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKGdlbnVzX1NDRkEsIHg9J0FjZXRhdGUnLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLGNvci5jb2VmLmNvb3JkID0gYyg1MCwgLTEuMSksIHhsYWI9ICdBY2V0YXRlIENvbmNlbnRyYXRpb24gW8K1bW9sL2cgRFddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0Fra2VybWFuc2lhJykrCnRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQ29yaW9iYWN0ZXJpaWEub19fQ29yaW9iYWN0ZXJpYWxlcy5mX19Db3Jpb2JhY3RlcmlhY2VhZS5nX19Db2xsaW5zZWxsYSwgeD1BY2V0YXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdBY2V0YXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db2xsaW5zZWxsYSApJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChnZW51c19TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMsIHg9QWNldGF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignQWNldGF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmFjdGVyb2lkZXMgKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpgYGAKCkxvb3AgUHJvcGlvbmF0IHVuZCBHZW51cy1MZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX1ByIDwtIGZpbHRlcihnZW51c19TQ0ZBLCAhaXMubmEoUHJvcGlvbmF0ZSkpCgpjb3JyX3NwZWFybWFuX2dlbnVzX1ByIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19QciwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRQcm9waW9uYXRlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJFByb3Bpb25hdGUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFByb3Bpb25hdGUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfUHIpKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX1ByW25yb3csIlNDRkEiXSA9ICJQcm9waW9uYXRlIgogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfUHJbbnJvdywgIkdlbnVzIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19Qcltucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfUHJbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19Qcltucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19Qcltucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfUHJbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19Qcltucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fZ2VudXNfUHIkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1ByJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfUHIkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19QciRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19QciRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19QciRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCgpjb3JyX3NpZ19nZW51c19QciA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9nZW51c19QciwgcC5hZGp1c3RlZCA8IDAuMDUgfCBwLmFkanVzdGVkX1BSRSA8IDAuMDUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjA1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9nZW51c19QciwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9TQ0ZBL1NDRkEgYW5hbHlzZS9TQ0ZBIFRhYmVsbGUvR2VudXMuUHIudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgpQbG90dGVuIFByb3Bpb25hdCB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSwgeD1Qcm9waW9uYXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdQcm9waW9uYXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChnZW51c19TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUmlrZW5lbGxhY2VhZS5nX18sIHg9UHJvcGlvbmF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignUHJvcGlvbmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZl9fUmlrZW5lbGxhY2VhZSknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dwbG90KGdlbnVzX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fRXJ5c2lwZWxvdHJpY2hpLm9fX0VyeXNpcGVsb3RyaWNoYWxlcy5mX19FcnlzaXBlbG90cmljaGFjZWFlLmdfXywgeD1Qcm9waW9uYXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdQcm9waW9uYXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19FcnlzaXBlbG90cmljaGFjZWFlKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEsIHg9UHJvcGlvbmF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignUHJvcGlvbmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQWtrZXJtYW5zaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCgpgYGAKCkxvb3AgQnV0eXJhdCB1bmQgR2VudXMtTGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9nZW51c19CdSA8LSBmaWx0ZXIoZ2VudXNfU0NGQSwgIWlzLm5hKEJ1dHlyYXRlKSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfQnUgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX0J1LCAhaXMubmEoaSkpCiAgCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJEJ1dHlyYXRlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIsIHBhaWVkID0gVCkKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkQnV0eXJhdGUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIsIHBhaWVkID0gVCkKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkQnV0eXJhdGUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iLCBwYWllZCA9IFQpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19CdSkrMQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfQnVbbnJvdywiU0NGQSJdID0gIkJ1dHlyYXRlIgogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfQnVbbnJvdywgIkdlbnVzIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19CdVtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfQnVbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19CdVtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19CdVtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfQnVbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19CdVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fZ2VudXNfQnUkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX0J1JHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfQnUkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19CdSRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19CdSRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19CdSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc2lnX2dlbnVzX0J1IDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX2dlbnVzX0J1LCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX2dlbnVzX0J1LCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL1NDRkEvU0NGQSBhbmFseXNlL1NDRkEgVGFiZWxsZS9HZW51cy5CdS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gQnV0eXJhdCB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSwgeD1CdXR5cmF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignQnV0eXJhdGUgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYSknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dwbG90KGdlbnVzX1NDRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fRXJ5c2lwZWxvdHJpY2hpLm9fX0VyeXNpcGVsb3RyaWNoYWxlcy5mX19FcnlzaXBlbG90cmljaGFjZWFlLmdfXywgeD1CdXR5cmF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignQnV0eXJhdGUgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGZfX0VyeXNpcGVsb3RyaWNoYWNlYWUpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChnZW51c19TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUmlrZW5lbGxhY2VhZS5nX18sIHg9QnV0eXJhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0J1dHlyYXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19SaWtlbmVsbGFjZWFlKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXy5SdW1pbm9jb2NjdXMuLCB4PUJ1dHlyYXRlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdCdXR5cmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fLlJ1bWlub2NvY2N1cyknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKYGBgCgpMb29wIElzb2J1dHlyYXQgdW5kIEdlbnVzLUxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfQkkgPC0gZmlsdGVyKGdlbnVzX1NDRkEsICFpcy5uYShJc28uQnV0eXJhdGUpKQoKY29ycl9zcGVhcm1hbl9nZW51c19CSSA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBnZW51c19jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfZ2VudXNfQkksICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkSXNvLkJ1dHlyYXRlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIsIHBhaXJlZCA9IFQpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJElzby5CdXR5cmF0ZQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIiwgcGFpcmVkID0gVCkKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkSXNvLkJ1dHlyYXRlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIiwgcGFpZWQgPSBUKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfQkkpKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX0JJW25yb3csIlNDRkEiXSA9ICJJc28uQnV0eXJhdGUiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19CSVtucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX0JJW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19CSVtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX0JJW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX0JJW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19CSVtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX0JJW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c19CSSRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfQkkkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19CSSRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX0JJJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX0JJJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX0JJJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCmNvcnJfc2lnX2dlbnVzX0JJIDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX2dlbnVzX0JJLCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX2dlbnVzX0JJLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL1NDRkEvU0NGQSBhbmFseXNlL1NDRkEgVGFiZWxsZS9HZW51cy5CSS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gSXNvYnV0eXJhdCBnZW51cy1sZXZlbAoKYGBge3J9CmdncGxvdChnZW51c19TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19Db3Jpb2JhY3RlcmlpYS5vX19Db3Jpb2JhY3RlcmlhbGVzLmZfX0NvcmlvYmFjdGVyaWFjZWFlLmdfXywgeD1Jc28uQnV0eXJhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0lzby5CdXR5cmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZl9fQ29yaW9iYWN0ZXJpYWNlYWUpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChnZW51c19TQ0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19BbHBoYXByb3Rlb2JhY3RlcmlhLm9fX1JGMzIuZl9fLmdfXywgeD1Jc28uQnV0eXJhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0lzby5CdXR5cmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgY19fQWxwaGFwcm90ZW9iYWN0ZXJpYS5vX19SRjMyKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fLmdfXywgeD1Jc28uQnV0eXJhdGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0lzby5CdXR5cmF0ZSBDb25jZW50cmF0aW9uIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzLCB4PUlzby5CdXR5cmF0ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignSXNvLkJ1dHlyYXRlIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db3Byb2NvY2N1cyknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKCmBgYAoKTG9vcCB0b3RhbCBTQ0ZBIHVuZCBHZW51cy1MZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX1RTIDwtIGZpbHRlcihnZW51c19TQ0ZBLCAhaXMubmEoVG90YWwuU0NGQSkpCgpjb3JyX3NwZWFybWFuX2dlbnVzX1RTIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19UUywgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRUb3RhbC5TQ0ZBCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIsIHBhaXJlZCA9IFQpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJFRvdGFsLlNDRkEKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIsIHBhaXJlZCA9IFQpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFRvdGFsLlNDRkEKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iLCBwYWlyZWQgPSBUKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfVFMpKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX1RTW25yb3csIlNDRkEiXSA9ICJUb3RhbC5TQ0ZBIgogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfVFNbbnJvdywgIkdlbnVzIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19UU1tucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfVFNbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19UU1tucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19UU1tucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfVFNbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19UU1tucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fZ2VudXNfVFMkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1RTJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfVFMkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19UUyRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19UUyRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19UUyRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc2lnX2dlbnVzX1RTIDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX2dlbnVzX1RTLCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX2dlbnVzX1RTLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL1NDRkEvU0NGQSBhbmFseXNlL1NDRkEgVGFiZWxsZS9HZW51cy5UUy50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gdG90YWwgU0NGQSB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSwgeD1Ub3RhbC5TQ0ZBKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdUb3RhbC5TQ0ZBIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX1Jpa2VuZWxsYWNlYWUuZ19fLCB4PVRvdGFsLlNDRkEpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ1RvdGFsLlNDRkEgW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19SaWtlbmVsbGFjZWFlKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19FcnlzaXBlbG90cmljaGkub19fRXJ5c2lwZWxvdHJpY2hhbGVzLmZfX0VyeXNpcGVsb3RyaWNoYWNlYWUuZ19fLCB4PVRvdGFsLlNDRkEpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ1RvdGFsLlNDRkEgW21nL21sXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19FcnlzaXBlbG90cmljaGFjZWFlKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bSwgeD1Ub3RhbC5TQ0ZBKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdUb3RhbC5TQ0ZBIFttZy9tbF0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmlmaWRvYmFjdGVyaXVtKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QoZ2VudXNfU0NGQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEsIHg9VG90YWwuU0NGQSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignVG90YWwuU0NGQSBbbWcvbWxdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0Fra2VybWFuc2lhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpgYGAKCkRhdGVuIHNpY2hlcm4KCgpgYGB7cn0KY29ycl9nZW51c19TQ0ZBIDwtIGRhdGFfZnJhbWUoKQoKY29ycl9nZW51c19TQ0ZBIDwtIGJpbmRfcm93cyhjb3JyX3NwZWFybWFuX2dlbnVzX0FjLCBjb3JyX3NwZWFybWFuX2dlbnVzX1ByLGNvcnJfc3BlYXJtYW5fZ2VudXNfQnUsIGNvcnJfc3BlYXJtYW5fZ2VudXNfQkksIGNvcnJfc3BlYXJtYW5fZ2VudXNfVFMpCgp3cml0ZS50YWJsZShjb3JyX2dlbnVzX1NDRkEsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvcmVsYXRpdmUgYWJ1bmRhbmNlL2NvcnJfZ2VudXNfU0NGQV9hbGxfUFJFX1BPU1QudHh0Jywgc2VwID0gIlx0IiwgY29sLm5hbWVzID0gVFJVRSwgcm93Lm5hbWVzID0gRkFMU0UpCgpjb3JyX2dlbnVzX1NDRkFfc2lnIDwtIGRhdGFfZnJhbWUoKQoKY29ycl9nZW51c19TQ0ZBX3NpZyA8LSBiaW5kX3Jvd3MoY29ycl9zaWdfZ2VudXNfQWMsIGNvcnJfc2lnX2dlbnVzX1ByLCBjb3JyX3NpZ19nZW51c19CdSwgY29ycl9zaWdfZ2VudXNfQkksIGNvcnJfc2lnX2dlbnVzX1RTKQoKd3JpdGUudGFibGUoY29ycl9nZW51c19TQ0ZBX3NpZywgZmlsZSA9Jy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3JlbGF0aXZlIGFidW5kYW5jZS9jb3JyX2dlbnVzX1NDRkFfc2lnX1BSRV9QT1NULnR4dCcsc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLCByb3cubmFtZXMgPSBGQUxTRSkKCmBgYAoKMS43IFRlc3RlbiB2b24gVW50ZXJzY2hpZWRlbiBpbSByZWxhdGl2ZW4gVm9ya29tbWVuIGRlciBUYXhhIHZvbiBQcm9iYW5kZW4gbWl0IHNlaHIgaG9oZW4gU0NGQS1Lb256ZW50cmF0aW9uZW4gdW5kIG5vcm1hbGVuIFNDRkEtS29uemVudHJhdGlvbmVuCgpMYWRlbiBkZXIgTWV0YWRhdGVuCgpgYGB7cn0KU0NGQV9QdCA8LSByZWFkLnRhYmxlKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9TQ0ZBL1NDRkEgVGFiZWxsZSBQaGVub3R5cGVuLnR4dCIsIHNlcCA9J1x0Jyxjb21tZW50PScnLGhlYWQ9VCkKClNDRkFfUHRbICw2XSA8LSBOVUxMCmBgYAoKU3luY2hvbmlzaWVyZW4gZGVyIE1ldGFkYXRlbgoKYGBge3J9ClNDRkFfUHQgPC0gbXV0YXRlKFNDRkFfUHQsIFNhbXBsZUlEMSA9IHBhc3RlKFByb2JhbmQsIFRpbWUsIHNlcCA9ICIuIikpCgpyb3cubmFtZXMoU0NGQV9QdCkgPC0gU0NGQV9QdCRTYW1wbGVJRDEKCmNvbW1vbi5pZHMucmVsYWIgPC0gaW50ZXJzZWN0KHJvd25hbWVzKFNDRkFfUHQpLCByb3duYW1lcyhyZWxhYl9waHlsdW1fSUQpKQoKU0NGQV9QdCA8LSBTQ0ZBX1B0W2NvbW1vbi5pZHMucmVsYWIsXQoKcmVsYWJfcGh5bHVtX0lEIDwtIHJlbGFiX3BoeWx1bV9JRFtjb21tb24uaWRzLnJlbGFiLF0KCnJlbGFiX2dlbnVzX0lEIDwtIHJlbGFiX2dlbnVzX0lEW2NvbW1vbi5pZHMucmVsYWIsXQpgYGAKCk1hdHJpeCBlcnN0ZWxsZW4sIGZpbHRlcm4sIGhpbnp1ZnVlZ2VuIHZvbiBsb2cgdW5kIFBzZWRvY291bnQKCmBgYHtyfQp3cml0ZS50YWJsZShTQ0ZBX3N0b29sLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL1NDRkEvU0NGQV9QdC50eHQnLCBzZXA9ICJcdCIsIGNvbC5uYW1lcyA9IFRSVUUsIHJvdy5uYW1lcyA9IEZBTFNFKQoKcmVsYWJfcGh5bHVtX0lEX2xvZyA8LSByZWxhYl9waHlsdW1fSURbLGMoMzo4KV0gKyAwLjEKCnJlbGFiX3BoeWx1bV9JRF9sb2cgPC0gbG9nMTAocmVsYWJfcGh5bHVtX0lEX2xvZykKCnBoeWx1bV9QdCA8LSBjYmluZChyZWxhYl9waHlsdW1fSURfbG9nLCBTQ0ZBX1B0WywgYygxLCAzOjUsIDc6MTEsIDE0KV0pCmBgYAoKUGh5bHVtLURpZmZlcmVuemVuIHp3c2ljaGVuIGRlbiBQaGFlbm90eXBlbgoKYGBge3J9CmNvbXBhcmlzb25fY29uIDwtIGxpc3QoYygibG93IGNvbmNlbnRyYXRpb25zIiwgImhpZ2ggY29uY2VudHJhdGlvbnMiKSkKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1B0LCBUaW1lID09ICJQUkUiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcywgc3Vic2V0KGZpbHRlcihwaHlsdW1fUHQsIFRpbWUgPT0gIlBSRSIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIocGh5bHVtX1B0KSksIGFlcyh4PVBoZW5vdHlwZSx5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMpKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpICsKZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCmdlb21fZG90cGxvdChiaW5heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yID0gJ2dyZXkyMicpICsKICBmYWNldF93cmFwKH5UaW1lKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSwgYWVzKGxhYmVsID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX2NvbikKCnBoeWx1bV9QdCRrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fUHQsIFRpbWUgPT0gIlBSRSIpKSRrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYSwgc3Vic2V0KGZpbHRlcihwaHlsdW1fUHQsIFRpbWUgPT0gIlBSRSIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIocGh5bHVtX1B0KSksIGFlcyh4PVBoZW5vdHlwZSx5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhKSkgKyB4bGFiKCdQaGVub3R5cGUnKSArIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykgKwogIGdlb21fYm94cGxvdChmaWxsID0gJ3doaXRlc21va2UnLCBjb2xvcj0iYmxhY2siKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yID0gJ2dyZXkyMicpICsKICBmYWNldF93cmFwKH5UaW1lKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSwgYWVzKGxhYmVsID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX2NvbikKCnBoeWx1bV9QdCRrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1B0LCBUaW1lID09ICJQUkUiKSkka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcywgc3Vic2V0KGZpbHRlcihwaHlsdW1fUHQsIFRpbWUgPT0gIlBSRSIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKCmdncGxvdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9QdCkpLCBhZXMoeD1QaGVub3R5cGUseT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzKSkgKyB4bGFiKCdQaGVub3R5cGUnKSArIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fY29uKQoKCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9QdCwgVGltZSA9PSAiUFJFIikpJGtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9QdCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRkFMU0UpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fUHQpKSwgYWVzKHg9UGhlbm90eXBlLHk9a19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEpKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYSknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fY29uKQoKCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9QdCwgVGltZSA9PSAiUFJFIikpJGtfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9QdCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRkFMU0UpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fUHQpKSwgYWVzKHg9UGhlbm90eXBlLHk9a19fQmFjdGVyaWEucF9fVGVuZXJpY3V0ZXMpKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcyknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fY29uKQoKCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9QdCwgVGltZSA9PSAiUFJFIikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSwgc3Vic2V0KGZpbHRlcihwaHlsdW1fUHQsIFRpbWUgPT0gIlBSRSIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIocGh5bHVtX1B0KSksIGFlcyh4PVBoZW5vdHlwZSx5PWtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSkpICsgeGxhYignUGhlbm90eXBlJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fY29uKQoKYGBgCjEuOCBCZXRhLURpdmVyc2l0YWV0CgpMYWRlbiB1bmQgZmlsdGVybiBkZXIgTWV0YWRhdGVuIAoKYGBge3J9Cm90dXNfbWVhbnMgPC0gcmVhZC50YWJsZSgiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvb3R1c19tZWFuc19zdG9vbCAyLnR4dCIsIHNlcCA9J1x0Jyxjb21tZW50PScnLGhlYWQ9VCkKCnNldHdkKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9TQ0ZBIikKCm1hcF9iZGl2IDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL01hcHBpbmdmaWxlXzE2U3JSTkFfQkMyMi50eHQiLCBzZXAgPSdcdCcsY29tbWVudD0nJyxoZWFkPVQpCgptYXBfYmRpdiA8LSBtdXRhdGUobWFwX2JkaXYsIFNhbXBsZUlEMiA9IHBhc3RlKFByb2JhbmQsIFRpbWUsIHNlcCA9ICIuIikpCgptYXBfYmRpdiA8LSBmaWx0ZXIobWFwX2JkaXYsIFRpbWVwb2ludCA9PSAiMFUxIiB8IFRpbWVwb2ludCA9PSIwVTIiIHwgVGltZXBvaW50ID09IjBVMyIpCgptYXBfYmRpdiA8LSBmaWx0ZXIobWFwX2JkaXYsIEJvZHlzaXRlID09ICJTdG9vbCIpCgpyb3duYW1lcyhtYXBfYmRpdikgPC0gbWFwX2JkaXYkU2FtcGxlSUQyCmBgYAoKU3luY2hvbmlzaWVyZW4gZGVyIERhdGVuCgpgYGB7cn0Kb3R1c19yZWxhYiA8LSBtdXRhdGUob3R1c19tZWFucywgU2FtcGxlSUQgPSBwYXN0ZShQcm9iYW5kLCBUaW1lLCBzZXAgPSAiLiIpKQoKcm93bmFtZXMob3R1c19yZWxhYikgPC0gb3R1c19yZWxhYiRTYW1wbGVJRAoKb3R1c19yZWxhYiA8LSBzd2VlcChvdHVzX3JlbGFiWywgMjo4NDYwNl0sIDEsIHJvd1N1bXMob3R1c19yZWxhYlssIDI6ODQ2MDZdKSwgJy8nKQoKZGltKG90dXNfcmVsYWIpCgpjb21tb24uaWRzLnJlbGFiIDwtIGludGVyc2VjdChyb3duYW1lcyhtYXBfYmRpdiksIHJvd25hbWVzKG90dXNfcmVsYWIpKQoKbWFwX2JkaXYgPC0gbWFwX2JkaXZbY29tbW9uLmlkcy5yZWxhYixdCgpvdHVzX3JlbGFiIDwtIG90dXNfcmVsYWJbY29tbW9uLmlkcy5yZWxhYixdCgpkaW0ob3R1c19yZWxhYikKCndyaXRlLnRhYmxlKG90dXNfcmVsYWIsIGZpbGUgPSAib3R1c19yZWxhYl9iYy50eHQiLCBzZXAgPSAiXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKQnJheS1DdXJ0aXMgS2Fsa3VsYXRpb24KCmBgYHtyfQpkLmJyYXkgPC12ZWdkaXN0KG90dXNfcmVsYWIpCgptYXRyaXguYnJheTwtIGFzLm1hdHJpeChkLmJyYXkpCgp3cml0ZS50YWJsZShtYXRyaXguYnJheSwgZmlsZSA9ICJtYXRyaXguYnJheS50eHQiLCBzZXAgPSAiXHQiLCBjb2wubmFtZXMgPSBULCByb3cubmFtZXMgPSBUKQpgYGAKCkVyc3RlbGxlbiBlaW5lciBEaXN0YW5jZS1tYXRyaXgKKEFsbCBmdW5jdGlvbnMgdXNlZCBhcmUgY3JlYXRlZCBieSBEYW5pZWwgUG9kbGVzbnkgYW5kIHNhdmVkIGluIHRoZSBSIFNjcmlwdCAibW9kaWZ5X2Rpc3RtYXQuUiIuCk9wZW4gdGhlIHNjcmlwdCBpbiBSIGFuZCBydW4gYWxsIGZ1bmN0aW9ucy4gVGhleSB3aWxsIHRoZW4gYmUgbGlzdGVkIGluIHRoZSBFbnZpcm9ubWVudC4KY2FsbCB0aGUgZnVuY3Rpb24gd2l0aCB0aGUgZGlzdGFuY2UgbWF0cml4IGZvciB0aGlzIHByb2plY3QpCgpgYGB7cn0KZGlzdG1hdCA8LSBjbGVhbl9kaXN0bWF0KGFzLmRhdGEuZnJhbWUobWF0cml4LmJyYXkpKQoKZGlzdG1hdCA8LSBkaXN0bWF0X3RvX2xvbmcoZGlzdG1hdCwgcm1fZGlhZyA9IFRSVUUpCgpkaXN0bWF0X1BSRSA8LSBmaWx0ZXIoZGlzdG1hdCwgZ3JlcGwoJyouUFJFJywgZGlzdG1hdCRyb3cpICYgZ3JlcGwoJyouUFJFJywgZGlzdG1hdCRjb2wpKQoKZGlzdG1hdF9QT1NUIDwtIGZpbHRlcihkaXN0bWF0LCBncmVwbCgnKi5QT1NUJywgZGlzdG1hdCRyb3cpICYgZ3JlcGwoJyouUE9TVCcsIGRpc3RtYXQkY29sKSkKCmRpc3RtYXRfRlUgPC0gZmlsdGVyKGRpc3RtYXQsIGdyZXBsKCcqLkZPTExPVy1VUCcsIGRpc3RtYXQkcm93KSAmIGdyZXBsKCcqLkZPTExPVy1VUCcsIGRpc3RtYXQkY29sKSkKCmRpc3RtYXRfUFJFWydUaW1lJ10gPSAnUFJFJwoKZGlzdG1hdF9QT1NUWydUaW1lJ10gPSAnUE9TVCcKCmRpc3RtYXRfRlVbJ1RpbWUnXSA9ICdGT0xMT1ctVVAnCgpkaXN0bWF0X1BSRXZzUE9TVCA8LSBkYXRhX2ZyYW1lKCkKCmRpc3RtYXRfUFJFdnNQT1NUIDwtIGJpbmRfcm93cyhkaXN0bWF0X1BSRSwgZGlzdG1hdF9QT1NUKQoKZGlzdG1hdF9QUkV2c1BPU1QkVGltZSA8LSBmYWN0b3IoZGlzdG1hdF9QUkV2c1BPU1QkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmRpc3RtYXRfYWxsIDwtIGRhdGFfZnJhbWUoKQoKZGlzdG1hdF9hbGwgPC0gYmluZF9yb3dzKGRpc3RtYXRfUFJFLCBkaXN0bWF0X1BPU1QsIGRpc3RtYXRfRlUpCgpkaXN0bWF0X2FsbCRUaW1lIDwtIGZhY3RvcihkaXN0bWF0X2FsbCRUaW1lLCBsZXZlbHM9YygiUFJFIiwgIlBPU1QiLCAiRk9MTE9XLVVQIikpCgpgYGAKCkZpbHRlcm4gZnVlciBQcm9iZW4gbWl0IFBSRSB1bmQgUE9TVAoKYGBge3J9CmRpc3RtYXRfUFJFdnNQT1NUX3BhaXJzIDwtIGZpbHRlcihkaXN0bWF0X1BSRXZzUE9TVCwgIXJvdyA9PSAiMzFLRS5QT1NUIiAmICFyb3cgPT0iMzRXRi5QUkUiICYgIXJvdyA9PSAiNDVHTC5QT1NUIiAmICFyb3cgPT0gIjQ5UkouUFJFIiAmIXJvdyA9PSAiNTRTTC5QT1NUIiAmICFyb3cgPT0gIjcwUEwuUFJFIiAmICFyb3cgPT0gIjc0U0EuUE9TVCIpCgpkaXN0bWF0X1BSRXZzUE9TVF9wYWlycyA8LSBmaWx0ZXIoZGlzdG1hdF9QUkV2c1BPU1RfcGFpcnMsICFjb2wgPT0gIjMxS0UuUE9TVCIgJiFjb2wgPT0gIjM0V0YuUFJFIiAmICFjb2wgPT0gIjQ1R0wuUE9TVCIgJiAhY29sID09ICI0OVJKLlBSRSIgJiAhY29sID09ICI1NFNMLlBPU1QiICYgIWNvbCA9PSAiNzBQTC5QUkUiICYgIWNvbCA9PSAiNzRTQS5QT1NUIikKCmBgYAoKV2lsY294b24tVGVzdCBQUkUgdW5kIFBPU1QgKyBib3hwbG90CgpgYGB7cn0KcGFpcndpc2Uud2lsY294LnRlc3QoZGlzdG1hdF9QUkV2c1BPU1RfcGFpcnMkZGlzdGFuY2UsIGRpc3RtYXRfUFJFdnNQT1NUX3BhaXJzJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICJCSCIsIHBhaXJlZCA9IFRSVUUpCgpwYWlyd2lzZS53aWxjb3gudGVzdChkaXN0bWF0X1BSRXZzUE9TVF9wYWlycyRkaXN0YW5jZSwgZGlzdG1hdF9QUkV2c1BPU1RfcGFpcnMkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gIkJIIiwgcGFpcmVkID0gVFJVRSkKCmdncGxvdChkaXN0bWF0X1BSRXZzUE9TVF9wYWlycywgYWVzKHg9VGltZSwgeT1kaXN0YW5jZSkpICsgeGxhYignVGltZXBvaW50JykgKyB5bGFiKCdCcmF5LUN1cnRpcyBEaXNzaW1pbGFyaXR5IChiYXNlbGluZSBwZXIgcHJvYmFuZCknKSArIApnZW9tX2JveHBsb3QoZmlsbD0nd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgZ2VvbV9kb3RwbG90KGJpbmF4aXM9J3knLCBzdGFja2Rpcj0nY2VudGVyJywgZG90c2l6ZT0wLjIpICsKZ2d0aXRsZSgnQmV0YS1EaXZlcnNpdHkgYmV0d2VlbiBwcm9iYW5kcyBiZWZvcmUgYW5kIGFmdGVyIGEgNi13ZWVrIEtldG9nZW5pYyBEaWV0JykgKwpzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbiA9IGxpc3QoYygiUFJFIiwgIlBPU1QiKSksIHBhaXJlZCA9IFRSVUUsIGFlcyhsYWJlbD0gLi5wLnNpZ25pZi4uKSkKCmBgYAoKTWVhbiB1bmQgU0QgZsO8ciBQUkUgdW5kIFBPU1QKCmBgYHtyfQptZWFuKHN1YnNldChmaWx0ZXIoZGlzdG1hdF9QUkV2c1BPU1RfcGFpcnMsIFRpbWUgPT0gIlBSRSIpKSRkaXN0YW5jZSkKCnNkKHN1YnNldChmaWx0ZXIoZGlzdG1hdF9QUkV2c1BPU1RfcGFpcnMsIFRpbWUgPT0gIlBSRSIpKSRkaXN0YW5jZSkKCm1lYW4oc3Vic2V0KGZpbHRlcihkaXN0bWF0X1BSRXZzUE9TVF9wYWlycywgVGltZSA9PSAiUE9TVCIpKSRkaXN0YW5jZSkKCnNkKHN1YnNldChmaWx0ZXIoZGlzdG1hdF9QUkV2c1BPU1RfcGFpcnMsIFRpbWUgPT0gIlBPU1QiKSkkZGlzdGFuY2UpCmBgYAoKCgoyLiBGQS1BbmFseXNlCgoyLjEgTm9ybWFsdmVydGVpbHVuZwpNZXRhZGF0ZW4gTGFkZW4sIGZpbHRlcm4gdW5kIHNvcnRpZXJlbgoKYGBge3J9CkZBX3N0b29sIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL0ZhLmZlY2VzLjIudHh0Iiwgc2VwID0gJ1x0JywgY29tbWVudD0nJywKICAgICAgICAgICAgICAgICAgICAgICBoZWFkPVQpClZpZXcoRkFfc3Rvb2wpCgpGQV9zdG9vbCRUaW1lIDwtZmFjdG9yKEZBX3N0b29sJFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIikpCgpGQV9zdG9vbCA8LSBGQV9zdG9vbFstYyg1ODo2NCksXQoKRkFfc3Rvb2w8LSBhZGRfcm93bmFtZXMoRkFfc3Rvb2wsICJTYW1wbGVJRDEiKQpGQV9zdG9vbC5yPC0gYWRkX3Jvd25hbWVzKEZBX3N0b29sLCAiU2FtcGxlSUQxIikKCnJvdy5uYW1lcyhGQV9zdG9vbCkgPC0gRkFfc3Rvb2wkU2FtcGxlSUQKCmBgYAoKVGVzdGVuIGF1ZiBOb3JtYWx2ZXJ0ZWlsdW5nCgpgYGB7cn0KRkFfY29sbmFtZXMgPC0gY29sbmFtZXMoRkFfc3Rvb2xbLCBjKDc6MTkpXSkKCm5kLkZBPC0gZGF0YV9mcmFtZSgpCgpmb3IgKGkgaW4gRkFfY29sbmFtZXMpICB7CiAgZml0IDwtIHNoYXBpcm8udGVzdChhcy5tYXRyaXgoYXMuZGF0YS5mcmFtZShsYXBwbHkoRkFfc3Rvb2xbLGldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzLm51bWVyaWMpKSkpCiAgcCA9IGZpdCRwLnZhbHVlCiAgbnJvdyA9IG5yb3cobmQuRkEpKzEKICBuZC5GQVtucm93LCAiY29sdW1uIl0gPSBpCiAgbmQuRkFbbnJvdywgInAudmFsdWUiXSA9IHJvdW5kKHAsIDQpCn0KCnNpZ24ubmRfRkEgPC0gZmlsdGVyKG5kLkZBLCBwLnZhbHVlID4gMC4wNSkKYGBgCgpQbG90dGVuIGRlciBOb3JtYWx2ZXJ0ZWlsdW5nZW4KCmBgYHtyfQpnZ3FxcGxvdChGQV9zdG9vbCRzYXQsIHlsYWIgPSAiU2F0dXJhdGVkIEZBIGNvbmNlbnRyYXRpb24gbm1vbC9nIiwgeGxhYiA9ICJTYW1wbGVJRCIpCmdncXFwbG90KEZBX3N0b29sJG1vbm8udW5zYXQsIHlsYWIgPSAiTW9ubyB1bnNhdHVyYXRlZCBjb25jZW50cmF0aW9uIFtubW9sL2ddIiwgeGxhYiA9ICJTYW1wbGVJRCIpCmdncXFwbG90KEZBX3N0b29sJGRpLnVuc2F0LCB5bGFiID0gIkRpdW5zYXR1cmF0ZWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXSIsIHhsYWIgPSAiU2FtcGxlSUQiKQpnZ3FxcGxvdChGQV9zdG9vbCRsZXNzLjE0LCB5bGFiID0gIiA8IDE0IGMtYXRvbXMgY29uY2VudHJhdGlvbiBbbm1vbC9nXSIsIHhsYWIgPSAiU2FtcGxlSUQiKQpnZ3FxcGxvdChGQV9zdG9vbCRjMTguMTksIHlsYWIgPSAiRkEgd2l0aCAxOC0xOSBjLWF0b21zIGNvbmNlbnRyYXRpb24gW25tb2wvZ10iLCB4bGFiID0gIlNhbXBsZUlEIikKZ2dxcXBsb3QoRkFfc3Rvb2wkYzE0LjE3LCB5bGFiID0gIkZBIHdpdGggMTQtMTcgYy1hdG9tcyBjb25jZW50cmF0aW9uIFtubW9sL2ddIiwgeGxhYiA9ICJTYW1wbGVJRCIpCmdncXFwbG90KEZBX3N0b29sJGMyMC4yMSwgeWxhYiA9ICJGQSB3aXRoIDIwLTIxIGMtYXRvbXMgY29uY2VudHJhdGlvbiBbbm1vbC9nXSIsIHhsYWIgPSAiU2FtcGxlSUQiKQpnZ3FxcGxvdChGQV9zdG9vbCRjMjIuMjQsIHlsYWIgPSAiRkEgd2l0aCAyMi0yNCBjLWF0b21zIGNvbmNlbnRyYXRpb24gW25tb2wvZ10iLCB4bGFiID0gIlNhbXBsZUlEIikKZ2dxcXBsb3QoRkFfc3Rvb2wkdG90YWwsIHlsYWIgPSAiVG90YWwgRkEgY29uY2VudHJhdGlvbiBbbm1vbC9nXSIsIHhsYWIgPSAiU2FtcGxlSUQiKQpnZ3FxcGxvdChGQV9zdG9vbC5yJG4uMywgeWxhYiA9ICJPbWVnYSAzIEZBIGNvbmNlbnRyYXRpb24gW25tb2wvZ10iLCB4bGFiID0gIlNhbXBsZUlEIikKZ2dxcXBsb3QoRkFfc3Rvb2wuciRuLjYsIHlsYWIgPSAiT21lZ2EgNiBGQSBjb25jZW50cmF0aW9uIFtubW9sL2ddIiwgeGxhYiA9ICJTYW1wbGVJRCIpCmdncXFwbG90KEZBX3N0b29sLnIkcmF0aW82LjMsIHlsYWIgPSAiT21lZ2EgNi8zIHJhdGlvIFtubW9sL2ddIiwgeGxhYiA9ICJTYW1wbGVJRCIpCmBgYAoKRmlsdGVybiBuYWNoIFBSRSB1bmQgUE9TVCBQcm9iZW4KCmBgYHtyfQpGQV9zdG9vbF9wYWlycyA8LSBmaWx0ZXIoRkFfc3Rvb2wsIFByb2JhbmQgPT0gIjA1QVAiIHwgUHJvYmFuZCA9PSAiMDZXVCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMDdSVyIgfCBQcm9iYW5kID09ICIxM0JTIiB8IFByb2JhbmQgPT0gIjE3U0siCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjIyV1MiIHwgUHJvYmFuZCA9PSAiMjVGRSIgfCBQcm9iYW5kID09ICIyNkZCIgogICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIyOEhNIiB8IFByb2JhbmQgPT0gIjI5TUsiIHwgUHJvYmFuZCA9PSAiMzBIQiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzFLRSIgfCBQcm9iYW5kID09ICIzMkZHIiB8IFByb2JhbmQgPT0gIjM2RVIiCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjM3U0QiIHwgUHJvYmFuZCA9PSAiMzhBUiIgfCBQcm9iYW5kID09ICI0MFdBIgogICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI0MU1MIiB8IFByb2JhbmQgPT0gIjQ1R0wiIHwgUHJvYmFuZCA9PSAiNDdPVCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNTBETSIgfCBQcm9iYW5kID09ICI1M0JEIiB8IFByb2JhbmQgPT0gIjU0U0wiCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjU3TVQiIHwgUHJvYmFuZCA9PSAiNjlITCIgfCBQcm9iYW5kID09ICI3NFNBIikKCgoKRkFfc3Rvb2xfcGFpcnNfUFAgPC0gZmlsdGVyKEZBX3N0b29sX3BhaXJzLCBUaW1lPT0iUFJFIiB8IFRpbWU9PSJQT1NUIikKCgpGQV9zdG9vbF9wYWlyc19QUEZVIDwtIGZpbHRlcihGQV9zdG9vbCwgUHJvYmFuZCA9PSAiMDVBUCIgfCBQcm9iYW5kID09ICIxM0JTIiB8IFByb2JhbmQgPT0gIjE3U0siIHwgUHJvYmFuZCA9PSAiMjJXUyIgfCBQcm9iYW5kID09ICI0MFdBIiB8IFByb2JhbmQgPT0gIjQxTUwiIHwgUHJvYmFuZCA9PSAiNTRTTCIpCgpgYGAKCldpbGNveG9uLVRlc3Qgendpc2NoZW4gZGVuIFplaXRwdW5rdGVuIFBSRSB1bmQgUE9TVApFcnN0ZWxsZW4gZWluZXMgbmV1ZW4gRGF0YWZyYW1lcyAKCmBgYHtyfQp3aWxjb3hfRkE8LSBkYXRhX2ZyYW1lKCkKCmVudmlyb25tZW50KGZpbHRlcikKCmZvciAoaSBpbiBGQV9jb2xuYW1lcykgewogIAogIHRtcCA8LSBGQV9zdG9vbF9wYWlycyAlPiUgZHJvcF9uYShpKSAKICAKICB4IDwtIGFzLm1hdHJpeChhcy5kYXRhLmZyYW1lKGxhcHBseSh0bXBbLGldLCBhcy5udW1lcmljKSkpCiAgCiAgeSA8LSBGQV9zdG9vbF9wYWlycyRUaW1lIAogIAogIHRtcF93aWxjb3ggPC0gcGFpcndpc2Uud2lsY294LnRlc3QoeCwgeSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gVCkKICAKICBwIDwtIHRtcF93aWxjb3gkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KHdpbGNveF9GQSkrMQogIAogIHdpbGNveF9GQVtucm93LCAiTEkiXSA8LSBpIAogIAogIAogIHdpbGNveF9GQVtucm93LCAiTWVhbiBQUkUiXSA8LXJvdW5kKG1lYW4oc3Vic2V0KGZpbHRlcihGQV9zdG9vbF9wYWlycyxUaW1lID09ICJQUkUiKVssaV0sIWlzLm5hKGkpLG5hLnJtID0gVFJVRSksIDIsIG1lYW4sICBuYS5ybSA9IFRSVUUpLCA0KQogIAogIHdpbGNveF9GQVtucm93LCAic2QgUFJFIl0gPC1yb3VuZChzZChjKHN1YnNldChmaWx0ZXIoRkFfc3Rvb2xfcGFpcnMsVGltZSA9PSAiUFJFIilbLGldLCFpcy5uYShpKSxuYS5ybSA9IFRSVUUpLCBuYS5ybSA9IFRSVUUpKSwgNCkKICAKICB3aWxjb3hfRkFbbnJvdywgIk1lYW4gUE9TVCJdIDwtcm91bmQobWVhbihzdWJzZXQoZmlsdGVyKEZBX3N0b29sX3BhaXJzLFRpbWUgPT0gIlBPU1QiKVssaV0sIWlzLm5hKGkpLCBuYS5ybSA9IFRSVUUpLCAyLCBtZWFuLCAgbmEucm0gPSBUUlVFKSwgNCkKICAKICB3aWxjb3hfRkFbbnJvdywgInNkIFBPU1QiXSA8LSByb3VuZChzZChjKHN1YnNldChmaWx0ZXIoRkFfc3Rvb2xfcGFpcnMsVGltZSA9PSAiUE9TVCIpWyxpXSwhaXMubmEoaSksIG5hLnJtID0gVFJVRSksbmEucm0gPSBUUlVFKSksIDQpCiAgCiAgd2lsY294X0ZBW25yb3csICJwLnZhbHVlIl0gPC0gcm91bmQocCwgNCkgfQoKCndyaXRlLnRhYmxlKHdpbGNveF9GQSwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy9mYSB0YWJlbGxlbi9GQS5wcmUucG9zdC50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClplaXRwdW5rdGUgenVzYW1tZW4KCmBgYHtyfQp3aWxjb3hfRkExPC0gZGF0YV9mcmFtZSgpCgpmb3IgKGkgaW4gRkFfY29sbmFtZXMpIHsKICAKICB0bXAgPC0gRkFfc3Rvb2xfcGFpcnMgJT4lIGRyb3BfbmEoaSkgCiAgCiAgeCA8LSBhcy5tYXRyaXgoYXMuZGF0YS5mcmFtZShsYXBwbHkodG1wWyxpXSwgYXMubnVtZXJpYykpKQogIAogIHkgPC0gRkFfc3Rvb2xfcGFpcnMkVGltZSAKICAKICB0bXBfd2lsY294IDwtIHBhaXJ3aXNlLndpbGNveC50ZXN0KHgsIHksIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IFQpCiAgCiAgcCA8LSB0bXBfd2lsY294JHAudmFsdWUKICAKICBucm93ID0gbnJvdyh3aWxjb3hfRkExKSsxCiAgCiAgd2lsY294X0ZBMVtucm93LCAiTEkiXSA8LSBpIAogIAogIHdpbGNveF9GQTFbbnJvdywgIk1lYW4iXSA8LXJvdW5kKG1lYW4oc3Vic2V0KGZpbHRlcihGQV9zdG9vbF9wYWlycylbLGldLCFpcy5uYShpKSxuYS5ybSA9IFRSVUUpLCAyLCBtZWFuLCAgbmEucm0gPSBUUlVFKSwgNCkKICAKICB3aWxjb3hfRkExW25yb3csICJzZCJdIDwtcm91bmQoc2QoYyhzdWJzZXQoZmlsdGVyKEZBX3N0b29sX3BhaXJzKVssaV0sIWlzLm5hKGkpLG5hLnJtID0gVFJVRSksIG5hLnJtID0gVFJVRSkpLCA0KQogIAogIHdpbGNveF9GQTFbbnJvdywgInAudmFsdWUiXSA8LSByb3VuZChwLCA0KSB9Cgp3cml0ZS50YWJsZSh3aWxjb3hfRkExLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL2ZhIHRhYmVsbGVuL0ZBLmFsbHRpbWVzLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmBgYAoKQm94cGxvdCBkZXIgRkEgamUgWmVpdHB1bmt0CgpNZWx0IERhdGVuCgpgYGB7cn0KCkZBX3N0b29sLm1lbHQgPC0gbWVsdChGQV9zdG9vbF9wYWlycywgaWQudmFycyA9ICdUaW1lJywgbWVhc3VyZS52YXJzID0gYygnc2F0JywgJ21vbm8udW5zYXQnLCAnZGkudW5zYXQnLCAnbW9yZS4yLnVuc2F0JywgJ2xlc3MuMTQnLCAnYzE0LjE3JywgJ2MxOCcsICdjMjAuMjQnLCAndG90YWwnKSkKCkZBX3N0b29sLm1lbHQgPC0gZHBseXI6OnJlbmFtZShGQV9zdG9vbC5tZWx0LCBGQT12YXJpYWJsZSkKRkFfc3Rvb2wubWVsdCA8LSBkcGx5cjo6cmVuYW1lKEZBX3N0b29sLm1lbHQsIENvbmNlbnRyYXRpb249dmFsdWUpCgpnZ3Bsb3QoRkFfc3Rvb2wubWVsdCxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIHhsYWIgKCdUaW1lIFBvaW50JykgKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJzYXR1cmF0ZWQiLCAibW9ub3Vuc2F0dXJhdGVkIiwgImRpdW5zYXR1cmF0ZWQiLCAiPiAyIHVuc2F0dXJhdGVkIiwgIjwgYzE0IiwgImMgMTQtMTciLCAiYyAxOC0xOSIsICJjIDIwLTIxIiwgImMgMjItMjQiLCAidG90YWwiLCAiaXNvIiwgImFudGVpc28iKSwgCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygidG9tYXRvIiwgInllbGxvd2dyZWVuIiwgInN0ZWVsYmx1ZTIiLCAib3JjaGlkMiIsICJkZWVwcGluayIsICJicm93bjQiLCAiZGFya29yYW5nZTEiLCAiYmx1ZXZpb2xldCIsICJhcXVhbWFyaW5lMyIsICJkYXJrc2FsbW9uIiwgImN5YW4zIiwgImRhcmtncmVlbiIpKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFRSVUUsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkKCmBgYAoKUGxvdHMsIGRpZSBpbiBBcmJlaXQgdm9ya29tbWVuCgpuYWNoIFNhZXR0aWd1bmcKCmBgYHtyfQoKRkFfc3Rvb2wubWVsdC5zYXQgPC0gbWVsdChGQV9zdG9vbF9wYWlycywgaWQudmFycyA9ICdUaW1lJywgbWVhc3VyZS52YXJzID0gYygnc2F0JywgJ21vbm8udW5zYXQnLCAnZGkudW5zYXQnLCAnbW9yZS4yLnVuc2F0JykpCgpGQV9zdG9vbC5tZWx0LnNhdCA8LSBkcGx5cjo6cmVuYW1lKEZBX3N0b29sLm1lbHQuc2F0LCBGQT12YXJpYWJsZSkKRkFfc3Rvb2wubWVsdC5zYXQgPC0gZHBseXI6OnJlbmFtZShGQV9zdG9vbC5tZWx0LnNhdCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCkZBX3N0b29sLm1lbHQuc2F0JFRpbWUgPC0gZmFjdG9yKEZBX3N0b29sLm1lbHQuc2F0JFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIikpCgpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvRkEuREIuS0QucGRmIix3aWR0aD04LCBoZWlnaHQ9MTApCmdncGxvdChGQV9zdG9vbC5tZWx0LnNhdCxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIHhsYWIgKCdaZWl0cHVua3QnKSArIHlsYWIgKCdLb256ZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICBnZW9tX2JveHBsb3Qod2lkdGggPSAuNywgbHdkPTAuNykgICsgdGhlbWVfY2xhc3NpYygpKwogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscyA9IGMoIjAiLCAiMSIsICIyIiwgIjMtNiIpLCAKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCIjZjBmOWU4IiwgIiNiYWU0YmMiLCAiIzdiY2NjNCIsICIjMmI4Y2JlIikpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSxheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTYpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCmRldi5vZmYoKQoKCmBgYAoKTUNUcwoKYGBge3J9CkZBX3N0b29sLm1lbHQubWN0IDwtIG1lbHQoRkFfc3Rvb2xfcGFpcnMsIGlkLnZhcnMgPSAnVGltZScsIG1lYXN1cmUudmFycyA9IGMoJ2xlc3MuMTQnKSkKRkFfc3Rvb2wubWVsdC5tY3QgPC0gZHBseXI6OnJlbmFtZShGQV9zdG9vbC5tZWx0Lm1jdCwgRkE9dmFyaWFibGUpCkZBX3N0b29sLm1lbHQubWN0IDwtIGRwbHlyOjpyZW5hbWUoRkFfc3Rvb2wubWVsdC5tY3QsIENvbmNlbnRyYXRpb249dmFsdWUpCgpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvRkEuTUNULktELnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQpnZ3Bsb3QoRkFfc3Rvb2wubWVsdC5tY3QsYWVzKHg9VGltZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSkpICsKICB4bGFiICgnWmVpdHB1bmt0JykgKyB5bGFiICgnS29uemVudHJhdGlvbmVuIFtubW9sL2ddJykgKyAKICBnZW9tX2JveHBsb3Qod2lkdGggPSAuNywgbHdkPTAuNykgICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygiTUNUIiksIAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoIm5hdnkiKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIikpKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSxheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTYpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCmRldi5vZmYoKQoKYGBgCgpLZXR0ZW5sYWVuZ2UKCmBgYHtyfQpGQV9zdG9vbC5tZWx0LmtsIDwtIG1lbHQoRkFfc3Rvb2xfcGFpcnMsIGlkLnZhcnMgPSAnVGltZScsIG1lYXN1cmUudmFycyA9IGMoJ2xlc3MuMTQnLCdjMTQuMTcnLCAnYzE4JywgJ2MyMC4yNCcpKQoKRkFfc3Rvb2wubWVsdC5rbCRUaW1lIDwtIGZhY3RvcihGQV9zdG9vbC5tZWx0LmtsJFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIikpCgpGQV9zdG9vbC5tZWx0LmtsIDwtIGRwbHlyOjpyZW5hbWUoRkFfc3Rvb2wubWVsdC5rbCwgRkE9dmFyaWFibGUpCkZBX3N0b29sLm1lbHQua2wgPC0gZHBseXI6OnJlbmFtZShGQV9zdG9vbC5tZWx0LmtsLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL0ZBLktMLktELnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQpnZ3Bsb3QoRkFfc3Rvb2wubWVsdC5rbCxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIHhsYWIgKCdaZWl0cHVua3QnKSArIHlsYWIgKCdLb256ZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICBnZW9tX2JveHBsb3Qod2lkdGggPSAuNywgbHdkPTAuNykgICsgdGhlbWVfY2xhc3NpYygpKwogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscyA9IGMoIj4gMTQgYyAoTUNUKSIsImMgMTQtMTciLCAiYyAxOCIsICJjIDIwLTI0IiksIAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoIiNmMWVlZjYiLCAiI2JkYzllMSIsICIjNzRhOWNmIiwgIiMwNTcwYjAiKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNikpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKZGV2Lm9mZigpCgpgYGAKClRvdGFsIEZBCgpgYGB7cn0KRkFfc3Rvb2wubWVsdC50IDwtIG1lbHQoRkFfc3Rvb2xfcGFpcnMsIGlkLnZhcnMgPSAnVGltZScsIG1lYXN1cmUudmFycyA9IGMoJ3RvdGFsJykpCkZBX3N0b29sLm1lbHQudCA8LSBkcGx5cjo6cmVuYW1lKEZBX3N0b29sLm1lbHQudCwgRkE9dmFyaWFibGUpCkZBX3N0b29sLm1lbHQudCA8LSBkcGx5cjo6cmVuYW1lKEZBX3N0b29sLm1lbHQudCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCnBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9GQS50b3RhbC5LRC5wZGYiLHdpZHRoPTYsIGhlaWdodD0xMCkKZ2dwbG90KEZBX3N0b29sLm1lbHQudCxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIHhsYWIgKCdaZWl0cHVua3QnKSArIHlsYWIgKCdLb256ZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICBnZW9tX2JveHBsb3Qod2lkdGggPSAuMiwgbHdkPTEpICArIHRoZW1lX2NsYXNzaWMoKSsKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJHZXNhbXRmZXR0c8OkdXJlbiIpLCAKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJjb3JuZmxvd2VyYmx1ZSIpKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFRSVUUsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTE2KSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKSsKZXhwYW5kX2xpbWl0cyh5PWMoMCwgMzAwMCkpCmRldi5vZmYoKQpgYGAKCk9tZWdhLUZBCgpgYGB7cn0KRkFfc3Rvb2wubWVsdC5vIDwtIG1lbHQoRkFfc3Rvb2xfcGFpcnMsIGlkLnZhcnMgPSAnVGltZScsIG1lYXN1cmUudmFycyA9IGMoJ09tZWdhMycsICdPbWVnYTYnLCdyYXRpbycpKQpGQV9zdG9vbC5tZWx0Lm8gPC0gZHBseXI6OnJlbmFtZShGQV9zdG9vbC5tZWx0Lm8sIEZBPXZhcmlhYmxlKQpGQV9zdG9vbC5tZWx0Lm8gPC0gZHBseXI6OnJlbmFtZShGQV9zdG9vbC5tZWx0Lm8sIENvbmNlbnRyYXRpb249dmFsdWUpCgpGQV9zdG9vbC5tZWx0Lm8kVGltZSA8LSBmYWN0b3IoRkFfc3Rvb2wubWVsdC5vJFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIikpCgpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvRkEub21lZ2EuS0QucGRmIix3aWR0aD04LCBoZWlnaHQ9MTApCmdncGxvdChGQV9zdG9vbC5tZWx0Lm8sYWVzKHg9VGltZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSkpICsKICB4bGFiICgnWmVpdHB1bmt0JykgKyB5bGFiICgnS29uemVudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gLjYsIGx3ZD0wLjcpICArIHRoZW1lX2NsYXNzaWMoKSsKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJhbHBoYS1MaW5vbGVuc8OkdXJlIiwgIkxpbm9sc8OkdXJlIiwgIk9tZWdhIDYvT21lZ2EgMyBWZXJow6RsdG5pcyIpLCAKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCIjMmM3ZmI4IiwgIiM3ZmNkYmIiLCAiI2VkZjhiMSIpKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFRSVUUsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTE2KSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKSsKICBleHBhbmRfbGltaXRzKHk9YygwLCAzMDAwKSkKZGV2Lm9mZigpCgpgYGAKCkluIEFyYmVpdApLb3JyZWxhdGlvbiB6d2lzY2hlbiBTYWV0dGlndW5nIGRlciBGZXR0c2FldXJlbiB1bmQgS29uemVudHJhdGlvbiAKCgpgYGB7cn0KCkZBX3N0b29sLm1lbHQua2wkY2hhaW4ubGVuZ3RoIDwtIGFzLmludGVnZXIoRkFfc3Rvb2wubWVsdC5rbCRjaGFpbi5sZW5ndGgpCkZBX3N0b29sLm1lbHQua2wgPC0gbWVsdChGQV9zdG9vbF9wYWlyc19QUCwgaWQudmFycyA9ICdUaW1lJywgbWVhc3VyZS52YXJzID0gYyggJ2xlc3MuMTQnLCAnYzE0LjE3JywgJ2MxOCcpKQoKRkFfc3Rvb2wubWVsdC5rbC5wcmUgPC0gc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5tZWx0LmtsLCAhVGltZSA9PSdQT1NUJykpCgpGQV9zdG9vbC5tZWx0LmtsIDwtIGRwbHlyOjpyZW5hbWUoRkFfc3Rvb2wubWVsdC5rbCwgY2hhaW4ubGVuZ3RoPXZhcmlhYmxlKQpGQV9zdG9vbC5tZWx0LmtsIDwtIGRwbHlyOjpyZW5hbWUoRkFfc3Rvb2wubWVsdC5rbCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCnBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9LTC5Lb256ZW50cmF0aW9uLnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQpnZ3NjYXR0ZXIoRkFfc3Rvb2wubWVsdC5rbCwgeD0nY2hhaW4ubGVuZ3RoJywgeT0nQ29uY2VudHJhdGlvbicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCdza3libHVlJywgJ29yY2hpZCcpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBULCAKICAgICAgICAgIGNvci5jb2VmID0gVCwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDEsIDI1MDApLCBjb3IuY29lZi5zaXplID0gNSwgeGxhYj0gJy4uJywgeWxhYiA9ICdLb256ZW50cmF0aW9uIFtubW9sL2ddJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXM9ImZyZWUiKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmRldi5vZmYoKQoKCnBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9LTC5Lb256ZW50cmF0aW9uMi5wZGYiLHdpZHRoPTgsIGhlaWdodD0xMCkKZ2dzY2F0dGVyKEZBX3N0b29sLm1lbHQua2wsIHg9J2NoYWluLmxlbmd0aCcsIHk9J0NvbmNlbnRyYXRpb24nLCBhZGQgPSAncmVnLmxpbmUnLCBjb2xvciA9ICJncmV5NTkiLGZpbGwgPSAibGlnaHRncmF5Iixjb25mLmludCA9IFQsIAogICAgICAgICAgY29yLmNvZWYgPSBULCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoMSwgMjUwMCksIGNvci5jb2VmLnNpemUgPSA4LCB4bGFiPSAnLi4nLCB5bGFiID0gJ0tvbnplbnRyYXRpb24gW25tb2wvZ10nKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwpnZW9tX3BvaW50KGNvbG9yPSdibGFjaycsIHNpemU9Mi41KQpkZXYub2ZmKCkKCmNvci50ZXN0KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wubWVsdC5rbCkpJGNoYWluLmxlbmd0aCwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5tZWx0LmtsKSkkQ29uY2VudHJhdGlvbiwgbWV0aG9kID0gInNwZWFybWFuIiwgZXhhY3QgPSBGKQoKcC5hZGp1c3QoYygyLjJlLTE2KSwgbWV0aG9kID0gJ0JIJywgbj0xKQoKYGBgCihTID0gODczNTUsIHAtdmFsdWUgPCAyLjJlLTE2CmFsdGVybmF0aXZlIGh5cG90aGVzaXM6IHRydWUgcmhvIGlzIG5vdCBlcXVhbCB0byAwCnNhbXBsZSBlc3RpbWF0ZXM6CiAgcmhvIAowLjg2MTkzNDkgCnEtdmFsdWUgPTIuMmUtMTYpCgpCb3hwbG90cyBlaW56ZWxuZXIgRkFzIHp1IGRlbiBaZWl0cHVua3RlbiBQUkUgdW5kIFBPU1QKCnZvbiBnZXNhZXR0aWd0ZW4gRkEgYmlzIFRvdGFsIEZBCgpgYGB7cn0KCkZBX3N0b29sLm1lbHQuc2F0IDwtIG1lbHQoRkFfc3Rvb2xfcGFpcnNfUFAsIGlkLnZhcnMgPSAnVGltZScsIG1lYXN1cmUudmFycyA9IGMoJ3NhdCcpKQpGQV9zdG9vbC5tZWx0LnNhdCA8LSByZW5hbWUoRkFfc3Rvb2wubWVsdC5zYXQsIEZBPXZhcmlhYmxlKQpGQV9zdG9vbC5tZWx0LnNhdCA8LSByZW5hbWUoRkFfc3Rvb2wubWVsdC5zYXQsIENvbmNlbnRyYXRpb249dmFsdWUpCmdncGxvdChGQV9zdG9vbC5tZWx0LnNhdCxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIHhsYWIgKCdUaW1lIFBvaW50JykgKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJzYXR1cmF0ZWQiKSwgCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygidG9tYXRvIikpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKCkZBX3N0b29sLm1lbHQubXMgPC0gbWVsdChGQV9zdG9vbF9wYWlyc19QUCwgaWQudmFycyA9ICdUaW1lJywgbWVhc3VyZS52YXJzID0gYygnbW9uby51bnNhdCcpKQpGQV9zdG9vbC5tZWx0Lm1zIDwtIHJlbmFtZShGQV9zdG9vbC5tZWx0Lm1zLCBGQT12YXJpYWJsZSkKRkFfc3Rvb2wubWVsdC5tcyA8LSByZW5hbWUoRkFfc3Rvb2wubWVsdC5tcywgQ29uY2VudHJhdGlvbj12YWx1ZSkKY29tcGFyaXNvbl90aW1lIDwtIGxpc3QoYygiUFJFIiwgIlBPU1QiKSkKZ2dwbG90KEZBX3N0b29sLm1lbHQubXMsYWVzKHg9VGltZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSkpICsKICBmYWNldF9ncmlkKC5+IEZBKSArCiAgeGxhYiAoJ1RpbWUgUG9pbnQnKSArIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICBnZW9tX2JveHBsb3QoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscyA9IGMoIm1vbm91bnNhdHVyYXRlZCIpLCAKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJ5ZWxsb3dncmVlbiIpKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKSsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKCkZBX3N0b29sLm1lbHQuZHMgPC0gbWVsdChGQV9zdG9vbF9wYWlyc19QUCwgaWQudmFycyA9ICdUaW1lJywgbWVhc3VyZS52YXJzID0gYygnZGkudW5zYXQnKSkKRkFfc3Rvb2wubWVsdC5kcyA8LSByZW5hbWUoRkFfc3Rvb2wubWVsdC5kcywgRkE9dmFyaWFibGUpCkZBX3N0b29sLm1lbHQuZHMgPC0gcmVuYW1lKEZBX3N0b29sLm1lbHQuZHMsIENvbmNlbnRyYXRpb249dmFsdWUpCmNvbXBhcmlzb25fdGltZSA8LSBsaXN0KGMoIlBSRSIsICJQT1NUIikpCmdncGxvdChGQV9zdG9vbC5tZWx0LmRzLGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gRkEpKSArCiAgZmFjZXRfZ3JpZCgufiBGQSkgKwogIHhsYWIgKCdUaW1lIFBvaW50JykgKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJkaXVuc2F0dXJhdGVkIiksIAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoInN0ZWVsYmx1ZTIiKSkgKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3RpbWUpCgoKRkFfc3Rvb2wubWVsdC5tMnUgPC0gbWVsdChGQV9zdG9vbF9wYWlyc19QUCwgaWQudmFycyA9ICdUaW1lJywgbWVhc3VyZS52YXJzID0gYygnbW9yZS4yLnVuc2F0JykpCkZBX3N0b29sLm1lbHQubTJ1IDwtIHJlbmFtZShGQV9zdG9vbC5tZWx0Lm0ydSwgRkE9dmFyaWFibGUpCkZBX3N0b29sLm1lbHQubTJ1IDwtIHJlbmFtZShGQV9zdG9vbC5tZWx0Lm0ydSwgQ29uY2VudHJhdGlvbj12YWx1ZSkKY29tcGFyaXNvbl90aW1lIDwtIGxpc3QoYygiUFJFIiwgIlBPU1QiKSkKZ2dwbG90KEZBX3N0b29sLm1lbHQubTJ1LGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gRkEpKSArCiAgZmFjZXRfZ3JpZCgufiBGQSkgKwogIHhsYWIgKCdUaW1lIFBvaW50JykgKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCI+IDIgdW5zYXR1cmF0ZWQiKSwgCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygib3JjaGlkMiIpKSArCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikrCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fdGltZSkKCgoKRkFfc3Rvb2wubWVsdC4xNCA8LSBtZWx0KEZBX3N0b29sX3BhaXJzX1BQLCBpZC52YXJzID0gJ1RpbWUnLCBtZWFzdXJlLnZhcnMgPSBjKCdsZXNzLjE0JykpCkZBX3N0b29sLm1lbHQuMTQgPC0gcmVuYW1lKEZBX3N0b29sLm1lbHQuMTQsIEZBPXZhcmlhYmxlKQpGQV9zdG9vbC5tZWx0LjE0IDwtIHJlbmFtZShGQV9zdG9vbC5tZWx0LjE0LCBDb25jZW50cmF0aW9uPXZhbHVlKQpjb21wYXJpc29uX3RpbWUgPC0gbGlzdChjKCJQUkUiLCAiUE9TVCIpKQpnZ3Bsb3QoRkFfc3Rvb2wubWVsdC4xNCxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIGZhY2V0X2dyaWQoLn4gRkEpICsKICB4bGFiICgnVGltZSBQb2ludCcpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIGdlb21fYm94cGxvdCgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygiPCBjMTQiKSwgCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygiZGVlcHBpbmsiKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3RpbWUpKyB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgoKCkZBX3N0b29sLm1lbHQuMTQxNyA8LSBtZWx0KEZBX3N0b29sX3BhaXJzX1BQLCBpZC52YXJzID0gJ1RpbWUnLCBtZWFzdXJlLnZhcnMgPSBjKCdjMTQuMTcnKSkKRkFfc3Rvb2wubWVsdC4xNDE3IDwtIHJlbmFtZShGQV9zdG9vbC5tZWx0LjE0MTcsIEZBPXZhcmlhYmxlKQpGQV9zdG9vbC5tZWx0LjE0MTcgPC0gcmVuYW1lKEZBX3N0b29sLm1lbHQuMTQxNywgQ29uY2VudHJhdGlvbj12YWx1ZSkKY29tcGFyaXNvbl90aW1lIDwtIGxpc3QoYygiUFJFIiwgIlBPU1QiKSkKZ2dwbG90KEZBX3N0b29sLm1lbHQuMTQxNyxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIGZhY2V0X2dyaWQoLn4gRkEpICsKICB4bGFiICgnVGltZSBQb2ludCcpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIGdlb21fYm94cGxvdCgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygiYyAxNC0xNyIpLCAKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJicm93bjQiKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3RpbWUpCgoKCkZBX3N0b29sLm1lbHQuMTQxNyA8LSBtZWx0KEZBX3N0b29sX3BhaXJzLCBpZC52YXJzID0gJ1RpbWUnLCBtZWFzdXJlLnZhcnMgPSBjKCdjMTQuMTcnKSkKRkFfc3Rvb2wubWVsdC4xNDE3IDwtIHJlbmFtZShGQV9zdG9vbC5tZWx0LjE0MTcsIEZBPXZhcmlhYmxlKQpGQV9zdG9vbC5tZWx0LjE0MTcgPC0gcmVuYW1lKEZBX3N0b29sLm1lbHQuMTQxNywgQ29uY2VudHJhdGlvbj12YWx1ZSkKY29tcGFyaXNvbl90aW1lIDwtIGxpc3QoYygiUFJFIiwgIlBPU1QiKSkKZ2dwbG90KEZBX3N0b29sLm1lbHQuMTQxNyxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIGZhY2V0X2dyaWQoLn4gRkEpICsKICB4bGFiICgnVGltZSBQb2ludCcpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIGdlb21fYm94cGxvdCgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygiYyAxNC0xNyIpLCAKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJicm93bjQiKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3RpbWUpKyB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgoKCkZBX3N0b29sLm1lbHQuMTggPC0gbWVsdChGQV9zdG9vbF9wYWlyc19QUCwgaWQudmFycyA9ICdUaW1lJywgbWVhc3VyZS52YXJzID0gYygnYzE4LjE5JykpCkZBX3N0b29sLm1lbHQuMTggPC0gcmVuYW1lKEZBX3N0b29sLm1lbHQuMTgsIEZBPXZhcmlhYmxlKQpGQV9zdG9vbC5tZWx0LjE4IDwtIHJlbmFtZShGQV9zdG9vbC5tZWx0LjE4LCBDb25jZW50cmF0aW9uPXZhbHVlKQpjb21wYXJpc29uX3RpbWUgPC0gbGlzdChjKCJQUkUiLCAiUE9TVCIpKQpnZ3Bsb3QoRkFfc3Rvb2wubWVsdC4xOCxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIGZhY2V0X2dyaWQoLn4gRkEpICsKICB4bGFiICgnVGltZSBQb2ludCcpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIGdlb21fYm94cGxvdCgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygiYyAxOC0xOSIpLCAKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJkYXJrb3JhbmdlMSIpKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fdGltZSkrIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCgpGQV9zdG9vbC5tZWx0LjIwIDwtIG1lbHQoRkFfc3Rvb2xfcGFpcnNfUFAsIGlkLnZhcnMgPSAnVGltZScsIG1lYXN1cmUudmFycyA9IGMoJ2MyMC4yMScpKQpGQV9zdG9vbC5tZWx0LjIwIDwtIHJlbmFtZShGQV9zdG9vbC5tZWx0LjIwLCBGQT12YXJpYWJsZSkKRkFfc3Rvb2wubWVsdC4yMCA8LSByZW5hbWUoRkFfc3Rvb2wubWVsdC4yMCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKY29tcGFyaXNvbl90aW1lIDwtIGxpc3QoYygiUFJFIiwgIlBPU1QiKSkKZ2dwbG90KEZBX3N0b29sLm1lbHQuMjAsYWVzKHg9VGltZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSkpICsKICBmYWNldF9ncmlkKC5+IEZBKSArCiAgeGxhYiAoJ1RpbWUgUG9pbnQnKSArIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICBnZW9tX2JveHBsb3QoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscyA9IGMoImMgMjAtMjEiKSwgCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygiYmx1ZXZpb2xldCIpKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fdGltZSkrIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCgoKRkFfc3Rvb2wubWVsdC4yMiA8LSBtZWx0KEZBX3N0b29sX3BhaXJzX1BQLCBpZC52YXJzID0gJ1RpbWUnLCBtZWFzdXJlLnZhcnMgPSBjKCdjMjIuMjQnKSkKRkFfc3Rvb2wubWVsdC4yMiA8LSByZW5hbWUoRkFfc3Rvb2wubWVsdC4yMiwgRkE9dmFyaWFibGUpCkZBX3N0b29sLm1lbHQuMjIgPC0gcmVuYW1lKEZBX3N0b29sLm1lbHQuMjIsIENvbmNlbnRyYXRpb249dmFsdWUpCmNvbXBhcmlzb25fdGltZSA8LSBsaXN0KGMoIlBSRSIsICJQT1NUIikpCmdncGxvdChGQV9zdG9vbC5tZWx0LjIyLGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gRkEpKSArCiAgZmFjZXRfZ3JpZCgufiBGQSkgKwogIHhsYWIgKCdUaW1lIFBvaW50JykgKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJjIDIyLTI0IiksIAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoImFxdWFtYXJpbmUzIikpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gRiwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKSsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKCgpGQV9zdG9vbC5tZWx0LnQgPC0gbWVsdChGQV9zdG9vbF9wYWlyc19QUCwgaWQudmFycyA9ICdUaW1lJywgbWVhc3VyZS52YXJzID0gYygndG90YWwnKSkKRkFfc3Rvb2wubWVsdC50IDwtIHJlbmFtZShGQV9zdG9vbC5tZWx0LnQsIEZBPXZhcmlhYmxlKQpGQV9zdG9vbC5tZWx0LnQgPC0gcmVuYW1lKEZBX3N0b29sLm1lbHQudCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKY29tcGFyaXNvbl90aW1lIDwtIGxpc3QoYygiUFJFIiwgIlBPU1QiKSkKZ2dwbG90KEZBX3N0b29sLm1lbHQudCxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIGZhY2V0X2dyaWQoLn4gRkEpICsKICB4bGFiICgnVGltZSBQb2ludCcpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIGdlb21fYm94cGxvdCgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygidG90YWwiKSwgCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygiZGFya3NhbG1vbiIpKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fdGltZSkrIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCmBgYAoKS29ycmVsYXRpb24gendpc2NoZW4gQW56YWhsIGFuIERvcHBlbGJpbmR1bmdlbiB1bmQgS29uemVudHJhdGlvbiBkZXIgRkEKCkxhZGVuIGRlciBNZXRhZGF0ZW4KCmBgYHtyfQpGQV9zdG9vbC5kYiA8LSByZWFkLnRhYmxlKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9EQiBzw6R0dGlndW5nIC50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLAogICAgICAgICAgICAgICAgICAgICAgIGhlYWQ9VCkKRkFfc3Rvb2wuZGIkVGltZSA8LSBmYWN0b3IoRkFfc3Rvb2wuZGIkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKYGBgCgpQbG90dGVuIGRlciBLb3JyZWxhdGlvbgpJbiBBcmJlaXQKCmBgYHtyfQpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvREIuMktvbnplbnRyYXRpb24ucGRmIix3aWR0aD04LCBoZWlnaHQ9MTApCmdnc2NhdHRlcihGQV9zdG9vbC5kYiwgeD0nREInLCB5PSdDb25jZW50cmF0aW9uJyxjb2xvciA9ICJncmV5NTkiLGZpbGwgPSAibGlnaHRncmF5IixzaGFwZSA9IDE5LCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBULCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDAsIDMwMDApLCBjb3IuY29lZi5zaXplID0gNSwgeGxhYj0gJ0FuemFobCBhbiBEb3BwZWxiaW5kdW5nZW4nLCB5bGFiID0gJ0tvbnplbnRyYXRpb24gW25tb2wvZ10nKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdlb21fcG9pbnQoY29sb3I9J2JsYWNrJywgc2l6ZT0yLjUpCmRldi5vZmYoKQoKY29yLnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5kYikpJERCLCBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLmRiKSkkQ29uY2VudHJhdGlvbiwgbWV0aG9kID0gInNwZWFybWFuIiwgZXhhY3QgPSBGKQoKcC5hZGp1c3QoYygyLjJlLTE2KSwgbWV0aG9kID0gJ0JIJywgbj0xKQoKYGBgCihTID0gMzY4NDUwMCwgcC12YWx1ZSA8IDIuMmUtMTYKYWx0ZXJuYXRpdmUgaHlwb3RoZXNpczogdHJ1ZSByaG8gaXMgbm90IGVxdWFsIHRvIDAKc2FtcGxlIGVzdGltYXRlczoKIHJobyAKLTAuNzAzNDgwNykKCgoyLjIgS29ycmVsYXRpb25zYW5hbHlzZW4gendpc2NoZW4gZGVuIEZBcyBtaXQgSGlsZmUgZWluZXIgS29ycmVsYXRpb25zbWF0cml4CgpMYWRlbiBkZXIgTWV0YWRhdGVuCgpgYGB7cn0KRkFfc3Rvb2wgPC0gcmVhZC50YWJsZSgiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvRmEuZmVjZXMuMi50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLAogICAgICAgICAgICAgICAgICAgICAgIGhlYWQ9VCkKICAgICAgRkFfc3Rvb2wkVGltZSA8LWZhY3RvcihGQV9zdG9vbCRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKRkFfc3Rvb2wgPC0gRkFfc3Rvb2xbLWMoNTg6NjQpLF0KRkFfc3Rvb2wgPC0gRkFfCgpGQV9zdG9vbDwtIGFkZF9yb3duYW1lcyhGQV9zdG9vbCwgIlNhbXBsZUlEMSIpCkZBX3N0b29sLnI8LSBhZGRfcm93bmFtZXMoRkFfc3Rvb2wsICJTYW1wbGVJRDEiKQoKCnJvdy5uYW1lcyhGQV9zdG9vbCkgPC0gRkFfc3Rvb2wkU2FtcGxlSUQgICAgICAgICAgICAgICAgIApgYGAKCkZpbHRlcm4gbmFjaCBQUkUgdW5kIFBPU1QKSGluenVmw7xnZW4gdm9uIFNwZWFybWFuCgpgYGB7cn0KRkFfc3Rvb2xfbWF0cml4X1BSRSA8LSBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLCBUaW1lID09ICJQUkUiKSlbICw4OjE5XQpGQV9zdG9vbF9tYXRyaXhfUE9TVCA8LSBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLCBUaW1lID09ICJQT1NUIikpWyAsODoxOV0KCnJlcy5QUkUgPC0gY29yKEZBX3N0b29sX21hdHJpeF9QUkUpCnJlcy5QT1NUIDwtIGNvcihGQV9zdG9vbF9tYXRyaXhfUE9TVCkKCnJlczIuUFJFIDwtIHJjb3JyKGFzLm1hdHJpeChGQV9zdG9vbF9tYXRyaXhfUFJFKSwgdHlwZSA9ICJzcGVhcm1hbiIpCgoKcmVzMi5QT1NUIDwtIHJjb3JyKGFzLm1hdHJpeChGQV9zdG9vbF9tYXRyaXhfUE9TVCksIHR5cGUgPSAic3BlYXJtYW4iKQpgYGAKIEJlc3RpbW11bmcgZGVzIEtvcnJlbGF0aW9uc2tvZWZmaXppZW50ZW4KIApgYGB7cn0KcmVzMi5QUkUkcgpyZXMyLlBPU1QkcgoKRkFfc3Rvb2xfUFJFX0NDIDwtIGFzLm1hdHJpeCgocmVzMi5QUkUkcikpCkZBX3N0b29sX1BPU1RfQ0MgPC0gYXMubWF0cml4KHJlczIuUE9TVCRyKQpgYGAKIApCZXN0aW1tdW5nIHAtdmFsdWVzCgpgYGB7cn0KcmVzMiRQCgpGQV9zdG9vbF9QUkVfUFYgPC0gYXMubWF0cml4KHJlczIuUFJFJFApCkZBX3N0b29sX1BPU1RfUFYgPC0gYXMubWF0cml4KHJlczIuUE9TVCRQKQpgYGAKCkVyc3RlbGxlbiBlaW5lciBmbGF0dGVuQ29yck1hdHJpeCBmw7xyIFBSRSB1bmQgUE9TVAoKYGBge3J9CmZsYXR0ZW5Db3JyTWF0cml4LlBSRSA8LSBmdW5jdGlvbihGQV9zdG9vbF9QUkVfQ0MsIEZBX3N0b29sX1BSRV9QVikgewogIHV0IDwtIHVwcGVyLnRyaShGQV9zdG9vbF9QUkVfQ0MpCiAgZGF0YS5mcmFtZSgKICAgIHJvdyA9IHJvd25hbWVzKEZBX3N0b29sX1BSRV9DQylbcm93KEZBX3N0b29sX1BSRV9DQylbdXRdXSwKICAgIGNvbHVtbiA9IHJvd25hbWVzKEZBX3N0b29sX1BSRV9DQylbY29sKEZBX3N0b29sX1BSRV9DQylbdXRdXSwKICAgIGNvciAgPShGQV9zdG9vbF9QUkVfQ0MpW3V0XSwKICAgIHAgPSBGQV9zdG9vbF9QUkVfUFZbdXRdCiAgKQp9CgpmbGF0dGVuQ29yck1hdHJpeC5QUkUocmVzMi5QUkUkciwgcmVzMi5QUkUkUCkKCgpmbGF0dGVuQ29yck1hdHJpeC5QT1NUIDwtIGZ1bmN0aW9uKEZBX3N0b29sX1BPU1RfQ0MsIEZBX3N0b29sX1BPU1RfUFYpIHsKICB1dCA8LSB1cHBlci50cmkoRkFfc3Rvb2xfUE9TVF9DQykKICBkYXRhLmZyYW1lKAogICAgcm93ID0gcm93bmFtZXMoRkFfc3Rvb2xfUE9TVF9DQylbcm93KEZBX3N0b29sX1BPU1RfQ0MpW3V0XV0sCiAgICBjb2x1bW4gPSByb3duYW1lcyhGQV9zdG9vbF9QT1NUX0NDKVtjb2woRkFfc3Rvb2xfUE9TVF9DQylbdXRdXSwKICAgIGNvciAgPShGQV9zdG9vbF9QT1NUX0NDKVt1dF0sCiAgICBwID0gRkFfc3Rvb2xfUE9TVF9QVlt1dF0KICApCn0KCmZsYXR0ZW5Db3JyTWF0cml4LlBPU1QocmVzMi5QT1NUJHIsIHJlczIuUE9TVCRQKQpgYGAKCkRhdGFmcmFtZSBlcnN0ZWxsZW4gdW5kIFNwYWx0ZW4gdW1iZW5lbm5lbgoKYGBge3J9CkZBX1BSRV9jb3IucCA8LSBhcy5kYXRhLmZyYW1lKGZsYXR0ZW5Db3JyTWF0cml4LlBSRShyZXMyLlBSRSRyLCByZXMyLlBSRSRQKSkKRkFfUE9TVF9jb3IucCA8LSBhcy5kYXRhLmZyYW1lKGZsYXR0ZW5Db3JyTWF0cml4LlBPU1QocmVzMi5QT1NUJHIsIHJlczIuUE9TVCRQKSkKCgpjb2xuYW1lcyhGQV9QUkVfY29yLnApIDwtIGMoIkZBIiwgIkZBIiwgImNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IiwgInAtdmFsdWUiKQoKY29sbmFtZXMoRkFfUE9TVF9jb3IucCkgPC0gYygiRkEiLCAiRkEiLCAiY29ycmVsYXRpb24gY29lZmZpY2llbnQiLCAicC12YWx1ZSIpCmBgYAoKQ29ycmVsb2dyYW0gZXJzdGVsbGVuCmBgYHtyfQpjb3JycGxvdChyZXMuUFJFLCB0eXBlID0gInVwcGVyIiwgb3JkZXIgPSAiaGNsdXN0IiwgCiAgICAgICAgIHRsLmNvbCA9ICJibGFjayIsIHRsLnNydCA9IDQ1KQoKCmNvcnJwbG90KHJlcy5QT1NULCB0eXBlID0gInVwcGVyIiwgb3JkZXIgPSAiaGNsdXN0IiwgCiAgICAgICAgIHRsLmNvbCA9ICJibGFjayIsIHRsLnNydCA9IDQ1KQoKCmNvcnJwbG90KHJlczIuUFJFJHIsIHR5cGU9InVwcGVyIiwgb3JkZXI9ImhjbHVzdCIsIAogICAgICAgICBwLm1hdCA9IHJlczIuUFJFJFAsIHNpZy5sZXZlbCA9IDAuMDUsIGluc2lnID0gImJsYW5rIikKCmNvcnJwbG90KHJlczIuUFJFJHIsIHR5cGU9InVwcGVyIiwgb3JkZXI9ImhjbHVzdCIsIAogICAgICAgICBwLm1hdCA9IHJlczIuUFJFJFAsIHNpZy5sZXZlbCA9IDAuMDUsIGluc2lnID0gImJsYW5rIikKCmNvcnJwbG90KHJlczIuUE9TVCRyLCB0eXBlPSJ1cHBlciIsIG9yZGVyPSJoY2x1c3QiLCAKICAgICAgICAgcC5tYXQgPSByZXMyLlBPU1QkUCwgc2lnLmxldmVsID0gMC4wNSwgaW5zaWcgPSAiYmxhbmsiKQoKY29ycnBsb3QocmVzMi5QT1NUJHIsIHR5cGU9InVwcGVyIiwgb3JkZXI9ImhjbHVzdCIsIHAubWF0ID0gcmVzMi5QUkUkUCwgc2lnLmxldmVsID0gMC4wNSwgaW5zaWcgPSAiYmxhbmsiKQogIApgYGAKU2NhdHRlciBQbG90IGVyc3RlbGxlbiB1bmQgRGF0ZW4gc2ljaGVybgoKYGBge3J9CmNoYXJ0LkNvcnJlbGF0aW9uKEZBX3N0b29sX21hdHJpeF9QUkUsIGhpc3RvZ3JhbT1UUlVFLCBwY2g9MTkpCmNoYXJ0LkNvcnJlbGF0aW9uKEZBX3N0b29sX21hdHJpeF9QT1NULCBoaXN0b2dyYW0gPSBULCBwY2ggPSAxOSkgICAgICAgCiAgICAgICAgIAoKd3JpdGUudGFibGUoRkFfUE9TVF9jb3IucCwgZmlsZSA9Jy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL0ZBIGZlY2FsL2NvcnJlbGF0aW9ucy9GQSBwb3N0IGNvcnJlbGF0aW9ucyBjb3IgcCcsc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLCByb3cubmFtZXMgPSBGQUxTRSkKd3JpdGUudGFibGUoRkFfUFJFX2Nvci5wLCBmaWxlID0nL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvRkEgZmVjYWwvY29ycmVsYXRpb25zL0ZBIHByZSBjb3JyZWxhdGlvbnMgY29yIHAnLHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSwgcm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKCjIuMyBTdGVyb2xrb252ZXJ0aWVydW5nc3R5cGVuLUFuYWx5c2UgZGVyIEZBCgpMYWRlbiB1bmQgZmlsdGVybiBkZXIgTWV0YWRhdGVuCgoKYGBge3J9CkZBX3N0b29sIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL0ZhLmZlY2VzLjIudHh0Iiwgc2VwID0gJ1x0JywgY29tbWVudD0nJywKICAgICAgICAgICAgICAgICAgICAgICBoZWFkPVQpCgpGQV9zdG9vbCRUaW1lIDwtZmFjdG9yKEZBX3N0b29sJFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIiwgIkZPTExPVy1VUCIpKQoKRkFfc3Rvb2wgPC0gRkFfc3Rvb2xbLWMoNjUsIDY2KSwgXQoKcm93Lm5hbWVzKEZBX3N0b29sKSA8LSBGQV9zdG9vbCRTYW1wbGVJRAoKRkFfc3Rvb2wkVGltZSA8LWZhY3RvcihGQV9zdG9vbCRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIsICJGT0xMT1ctVVAiKSkKCkZBX3N0b29sWzEsNF08LSAiUFJFIgoKRkFfc3Rvb2xfcGFpcnMgPC0gZmlsdGVyKEZBX3N0b29sLCBQcm9iYW5kID09ICIwNUFQIiB8IFByb2JhbmQgPT0gIjA2V1QiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjA3UlciIHwgUHJvYmFuZCA9PSAiMTNCUyIgfCBQcm9iYW5kID09ICIxN1NLIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIyMldTIiB8IFByb2JhbmQgPT0gIjI1RkUiIHwgUHJvYmFuZCA9PSAiMjZGQiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMjhITSIgfCBQcm9iYW5kID09ICIyOU1LIiB8IFByb2JhbmQgPT0gIjMwSEIiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjMxS0UiIHwgUHJvYmFuZCA9PSAiMzJGRyIgfCBQcm9iYW5kID09ICIzNkVSIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzN1NEIiB8IFByb2JhbmQgPT0gIjM4QVIiIHwgUHJvYmFuZCA9PSAiNDBXQSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNDFNTCIgfCBQcm9iYW5kID09ICI0NUdMIiB8IFByb2JhbmQgPT0gIjQ3T1QiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjUwRE0iIHwgUHJvYmFuZCA9PSAiNTNCRCIgfCBQcm9iYW5kID09ICI1NFNMIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI1N01UIiB8IFByb2JhbmQgPT0gIjY5SEwiIHwgUHJvYmFuZCA9PSAiNzRTQSIpCgoKRkFfc3Rvb2xfcGFpcnNfUFAgPC0gZmlsdGVyKEZBX3N0b29sX3BhaXJzLCBUaW1lPT0iUFJFIiB8IFRpbWU9PSJQT1NUIikKCkZBX3N0b29sX3BhaXJzX1BQRlUgPC0gZmlsdGVyKEZBX3N0b29sLCBQcm9iYW5kID09ICIwNUFQIiB8IFByb2JhbmQgPT0gIjEzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQlMiIHwgUHJvYmFuZCA9PSAiMTdTSyIgfCBQcm9iYW5kID09ICIyMldTIiB8IFByb2JhbmQgPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjQwV0EiIHwgUHJvYmFuZCA9PSAiNDFNTCIgfCBQcm9iYW5kID09ICI1NFNMIikKCmBgYAoKSW4gaGlnaCB1bmQgbG93IENvbnZlcnRlciB1bnRlcnRlaWxlbgoKYGBge3J9Cmxvd2NvbnYgPC0gZmlsdGVyKEZBX3N0b29sLCBQcm9iYW5kID09ICIwNUFQIiB8IFByb2JhbmQgPT0gIjMzTVAiCiAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjM4QVIiIHwgUHJvYmFuZCA9PSAiNDBXQSIgfCBQcm9iYW5kID09ICI0MU1MIgogICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI0N09UIiB8IFByb2JhbmQgPT0gIjQ5UkoiIHwgUHJvYmFuZCA9PSAiNTBETSIpCgpsb3djb252WydQaGVub3R5cGUnXSA9ICdsb3cgY29udmVydGVyJwoKaGlnaGNvbnYgPC0gZmlsdGVyKEZBX3N0b29sLCBQcm9iYW5kID09ICIwNldUIiB8IFByb2JhbmQgPT0gIjA3UlciCiAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMTNCUyIgfCBQcm9iYW5kID09ICIxN1NLIiB8IFByb2JhbmQgPT0gIjIyV1MiCiAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMjVGRSIgfCBQcm9iYW5kID09ICIyNkZCIiB8IFByb2JhbmQgPT0gIjI5TUsiCiAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzBIQiIgfCBQcm9iYW5kID09ICIzMUtFIiB8IFByb2JhbmQgPT0gIjM2RVIiCiAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNDVHTCIgfCBQcm9iYW5kID09ICI1M0JEIiB8IFByb2JhbmQgPT0gIjU0U0wiCiAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNTdNVCIgfCBQcm9iYW5kID09ICI2OUhMIiB8IFByb2JhbmQgPT0gIjc0U0EiKQoKaGlnaGNvbnZbJ1BoZW5vdHlwZSddID0gJ2hpZ2ggY29udmVydGVyJwoKaGlnaGNvbnYkQ29udmVydGVyLlR5cGUgPC0gTlVMTApsb3djb252JENvbnZlcnRlci5UeXBlIDwtIE5VTEwKCm5vY29udiA8LSBmaWx0ZXIoRkFfc3Rvb2wsIFByb2JhbmQgPT0gIjI4SE0iIHwgUHJvYmFuZCA9PSAiMzJGRyIKICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjM0V0YiIHwgUHJvYmFuZCA9PSAiMzVBRCIgfCBQcm9iYW5kID09ICIzN1NEIgogICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzlEQSIgfCBQcm9iYW5kID09ICI2NkRHIiB8IFByb2JhbmQgPT0gIjcwUEwiKQoKbm9jb252WydQaGVub3R5cGUnXSA9ICdub3QgY2xhc3NpZmllZCcKCm5vY29udiRDb252ZXJ0ZXIuVHlwZSA8LSBOVUxMCgpjb252VCA8LSBkYXRhLmZyYW1lKCkKY29udlQgPC0gYmluZF9yb3dzKGxvd2NvbnYsIGhpZ2hjb252LCBub2NvbnYpCgpjb252VF9wYWlyZWQgPC0gZmlsdGVyKGNvbnZULCBQcm9iYW5kID09ICIwNUFQIiB8IFByb2JhbmQgPT0gIjA2V1QiCiAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIwN1JXIiB8IFByb2JhbmQgPT0gIjEzQlMiIHwgUHJvYmFuZCA9PSAiMTdTSyIKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjIyV1MiIHwgUHJvYmFuZCA9PSAiMjVGRSIgfCBQcm9iYW5kID09ICIyNkZCIgogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMjhITSIgfCBQcm9iYW5kID09ICIyOU1LIiB8IFByb2JhbmQgPT0gIjMwSEIiCiAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzMUtFIiB8IFByb2JhbmQgPT0gIjMyRkciIHwgUHJvYmFuZCA9PSAiMzZFUiIKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjM3U0QiIHwgUHJvYmFuZCA9PSAiMzhBUiIgfCBQcm9iYW5kID09ICI0MFdBIgogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNDFNTCIgfCBQcm9iYW5kID09ICI0NUdMIiB8IFByb2JhbmQgPT0gIjQ3T1QiCiAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI1MERNIiB8IFByb2JhbmQgPT0gIjUzQkQiIHwgUHJvYmFuZCA9PSAiNTRTTCIKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjU3TVQiIHwgUHJvYmFuZCA9PSAiNjlITCIgfCBQcm9iYW5kID09ICI3NFNBIikKCmNvbnZUX3BhaXJlZF9QUCA8LSBmaWx0ZXIoY29udlRfcGFpcmVkLCBUaW1lPT0iUFJFIiB8IFRpbWU9PSJQT1NUIikKCmNvbnZUX3BhaXJlZF9QUG5jIDwtIGZpbHRlcihzdWJzZXQoY29udlRfcGFpcmVkX1BQLCAhUGhlbm90eXBlID09ICJub3QgY2xhc3NpZmllZCIgKSkKCmNvbnZUX3BhaXJlZF9QUG5jLlBSRSA8LSBmaWx0ZXIoc3Vic2V0KGNvbnZUX3BhaXJlZF9QUG5jLCBUaW1lID09IlBSRSIpKQoKY29udlRfcGFpcmVkX1BQbmMuUE9TVCA8LSBmaWx0ZXIoc3Vic2V0KGNvbnZUX3BhaXJlZF9QUG5jLCBUaW1lID09IlBPU1QiKSkKCndyaXRlLnRhYmxlKGNvbnZULCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL0ZBIHN0ZXJvbCBjb252ZXJ0ZXIgdHlwZXMgJywgc2VwID0gIlx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKYGBgCgoKCkluIGhpZ2ggdW5kIGxvdyBDb252ZXJ0ZXIgdW50ZXJ0ZWlsZW4KCgpgYGB7cn0KbG93Y29udiA8LSBmaWx0ZXIoRkFfc3Rvb2wsIFByb2JhbmQgPT0gIjA1QVAiIHwgUHJvYmFuZCA9PSAiMzNNUCIKICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzhBUiIgfCBQcm9iYW5kID09ICI0MFdBIiB8IFByb2JhbmQgPT0gIjQxTUwiCiAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjQ3T1QiIHwgUHJvYmFuZCA9PSAiNDlSSiIgfCBQcm9iYW5kID09ICI1MERNIikKCmxvd2NvbnZbJ1BoZW5vdHlwZSddID0gJ2xvdyBjb252ZXJ0ZXInCgpoaWdoY29udiA8LSBmaWx0ZXIoRkFfc3Rvb2wsIFByb2JhbmQgPT0gIjA2V1QiIHwgUHJvYmFuZCA9PSAiMDdSVyIKICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIxM0JTIiB8IFByb2JhbmQgPT0gIjE3U0siIHwgUHJvYmFuZCA9PSAiMjJXUyIKICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIyNUZFIiB8IFByb2JhbmQgPT0gIjI2RkIiIHwgUHJvYmFuZCA9PSAiMjlNSyIKICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzMEhCIiB8IFByb2JhbmQgPT0gIjMxS0UiIHwgUHJvYmFuZCA9PSAiMzZFUiIKICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI0NUdMIiB8IFByb2JhbmQgPT0gIjUzQkQiIHwgUHJvYmFuZCA9PSAiNTRTTCIKICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI1N01UIiB8IFByb2JhbmQgPT0gIjY5SEwiIHwgUHJvYmFuZCA9PSAiNzRTQSIpCgpoaWdoY29udlsnUGhlbm90eXBlJ10gPSAnaGlnaCBjb252ZXJ0ZXInCgpoaWdoY29udiRDb252ZXJ0ZXIuVHlwZSA8LSBOVUxMCmxvd2NvbnYkQ29udmVydGVyLlR5cGUgPC0gTlVMTAoKbm9jb252IDwtIGZpbHRlcihGQV9zdG9vbCwgUHJvYmFuZCA9PSAiMjhITSIgfCBQcm9iYW5kID09ICIzMkZHIgogICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzRXRiIgfCBQcm9iYW5kID09ICIzNUFEIiB8IFByb2JhbmQgPT0gIjM3U0QiCiAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzOURBIiB8IFByb2JhbmQgPT0gIjY2REciIHwgUHJvYmFuZCA9PSAiNzBQTCIpCgpub2NvbnZbJ1BoZW5vdHlwZSddID0gJ25vdCBjbGFzc2lmaWVkJwoKbm9jb252JENvbnZlcnRlci5UeXBlIDwtIE5VTEwKCmNvbnZUIDwtIGRhdGEuZnJhbWUoKQpjb252VCA8LSBiaW5kX3Jvd3MobG93Y29udiwgaGlnaGNvbnYsIG5vY29udikKCmNvbnZUX3BhaXJlZCA8LSBmaWx0ZXIoY29udlQsIFByb2JhbmQgPT0gIjA1QVAiIHwgUHJvYmFuZCA9PSAiMDZXVCIKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjA3UlciIHwgUHJvYmFuZCA9PSAiMTNCUyIgfCBQcm9iYW5kID09ICIxN1NLIgogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMjJXUyIgfCBQcm9iYW5kID09ICIyNUZFIiB8IFByb2JhbmQgPT0gIjI2RkIiCiAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIyOEhNIiB8IFByb2JhbmQgPT0gIjI5TUsiIHwgUHJvYmFuZCA9PSAiMzBIQiIKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjMxS0UiIHwgUHJvYmFuZCA9PSAiMzJGRyIgfCBQcm9iYW5kID09ICIzNkVSIgogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzdTRCIgfCBQcm9iYW5kID09ICIzOEFSIiB8IFByb2JhbmQgPT0gIjQwV0EiCiAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI0MU1MIiB8IFByb2JhbmQgPT0gIjQ1R0wiIHwgUHJvYmFuZCA9PSAiNDdPVCIKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjUwRE0iIHwgUHJvYmFuZCA9PSAiNTNCRCIgfCBQcm9iYW5kID09ICI1NFNMIgogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNTdNVCIgfCBQcm9iYW5kID09ICI2OUhMIiB8IFByb2JhbmQgPT0gIjc0U0EiKQoKY29udlRfcGFpcmVkX1BQIDwtIGZpbHRlcihjb252VF9wYWlyZWQsIFRpbWU9PSJQUkUiIHwgVGltZT09IlBPU1QiKQoKY29udlRfcGFpcmVkX1BQbmMgPC0gZmlsdGVyKHN1YnNldChjb252VF9wYWlyZWRfUFAsICFQaGVub3R5cGUgPT0gIm5vdCBjbGFzc2lmaWVkIiApKQoKY29udlRfcGFpcmVkX1BQbmMuUFJFIDwtIGZpbHRlcihzdWJzZXQoY29udlRfcGFpcmVkX1BQbmMsIFRpbWUgPT0iUFJFIikpCgpjb252VF9wYWlyZWRfUFBuYy5QT1NUIDwtIGZpbHRlcihzdWJzZXQoY29udlRfcGFpcmVkX1BQbmMsIFRpbWUgPT0iUE9TVCIpKQoKd3JpdGUudGFibGUoY29udlQsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvRkEgc3Rlcm9sIGNvbnZlcnRlciB0eXBlcyAnLCBzZXAgPSAiXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQpgYGAKCkJveHBsb3QgYWxsZXIgRkEgamUgbmFjaCBTdGVyb2xrb252ZXJ0aWVydW5nc3R5cCB1bmQgWmVpdHB1bmt0Ck1lbHQgRGF0ZW5zZXQKQWxsZSBGQQoKYGBge3J9CgpGQV9zdG9vbC5tZWx0IDwtIG1lbHQoY29udlRfcGFpcmVkX1BQLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywgJ1RpbWUnKSwgbWVhc3VyZS52YXJzID0gYygnc2F0JywgJ21vbm8udW5zYXQnLCAnZGkudW5zYXQnLCAnbW9yZS4yLnVuc2F0JywgJ2xlc3MuMTQnLCAnYzE0LjE3JywgJ2MxOC4xOScsICdjMjAuMjEnLCAnYzIyLjI0JywgJ3RvdGFsJykpCkZBX3N0b29sLm1lbHQgPC0gc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5tZWx0LCAhUGhlbm90eXBlID09ICJub3QgY2xhc3NpZmllZCIpKQoKRkFfc3Rvb2wubWVsdCA8LSByZW5hbWUoRkFfc3Rvb2wubWVsdCwgRkE9dmFyaWFibGUpCkZBX3N0b29sLm1lbHQgPC0gcmVuYW1lKEZBX3N0b29sLm1lbHQsIENvbmNlbnRyYXRpb249dmFsdWUpCgogIGdncGxvdChGQV9zdG9vbC5tZWx0LGFlcyh4PVBoZW5vdHlwZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSkpICsKICB4bGFiICgnQ29udmVydGVyIHR5cGUnKSArIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICBnZW9tX2JveHBsb3QoKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgZmFjZXRfZ3JpZCguflRpbWUpKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJzYXR1cmF0ZWQiLCAibW9ub3Vuc2F0dXJhdGVkIiwgImRpdW5zYXR1cmF0ZWQiLCAiPiAyIHVuc2F0dXJhdGVkIiwgIjwgYzE0IiwgImMgMTQtMTciLCAiYyAxOC0xOSIsICJjIDIwLTIxIiwgImMgMjItMjQiLCAidG90YWwiKSwgCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygidG9tYXRvIiwgInllbGxvd2dyZWVuIiwgInN0ZWVsYmx1ZTIiLCAib3JjaGlkMiIsICJkZWVwcGluayIsICJicm93bjQiLCAiZGFya29yYW5nZTEiLCAiYmx1ZXZpb2xldCIsICJhcXVhbWFyaW5lMyIsICJkYXJrc2FsbW9uIikpCit0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKYGBgCgpHZXNhZXR0aWd0ZSBGQSArIHdpbGNveG9uIHRlc3QKaW4gQXJiZWl0CgpgYGB7cn0Kc2F0X3N0b29sLm1lbHQgPC0gbWVsdChjb252VF9wYWlyZWRfUFAsIGlkLnZhcnMgPSBjKCdQaGVub3R5cGUnLCdUaW1lJyksIG1lYXN1cmUudmFycyA9IGMoJ3NhdCcpKQpzYXRfc3Rvb2wubWVsdCA8LSByZW5hbWUoc2F0X3N0b29sLm1lbHQsIEZBPXZhcmlhYmxlKQpzYXRfc3Rvb2wubWVsdCA8LSByZW5hbWUoc2F0X3N0b29sLm1lbHQsIENvbmNlbnRyYXRpb249dmFsdWUpCgoKZ2dwbG90KGZpbHRlcihzYXRfc3Rvb2wubWVsdCwgIVRpbWU9PSJGT0xMT1ctVVAiICYgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9VGltZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSkpICsKICBmYWNldF9ncmlkKC5+IFBoZW5vdHlwZSkgKwogIHhsYWIgKCdUaW1lIFBvaW50JykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiU2F0dXJhdGVkIGZhdHR5IGFjaWRzIiksIHZhbHVlcyA9IGMoInllbGxvd2dyZWVuIikpKwogIGdlb21fYm94cGxvdCgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChmaWx0ZXIoc2F0X3N0b29sLm1lbHQsICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSkpICsKICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICB4bGFiICgnQ29udmVydGVyIHR5cGUnKSsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvZ10gJykgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9Yygic2F0dXJhdGVkIGZhdHR5IGFjaWQiKSwgdmFsdWVzID0gYygieWVsbG93Z3JlZW4iKSkrCiAgZ2VvbV9ib3hwbG90KCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiaGlnaCBjb252ZXJ0ZXIiLCAibG93IGNvbnZlcnRlciIpKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgptZWFuKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJoaWdoIGNvbnZlcnRlciIpKSRzYXQpIAoKc2Qoc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWRfUFAsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gImhpZ2ggY29udmVydGVyIikpJHNhdCkgCgptZWFuKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAiaGlnaCBjb252ZXJ0ZXIiKSkkc2F0KSAKCnNkKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAiaGlnaCBjb252ZXJ0ZXIiKSkkc2F0KSAKCgptZWFuKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJsb3cgY29udmVydGVyIikpJHNhdCkgCgpzZChzdWJzZXQoZmlsdGVyKGNvbnZUX3BhaXJlZF9QUCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAibG93IGNvbnZlcnRlciIpKSRzYXQpIAoKbWVhbihzdWJzZXQoZmlsdGVyKGNvbnZUX3BhaXJlZF9QUCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImxvdyBjb252ZXJ0ZXIiKSkkc2F0KSAKCnNkKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAibG93IGNvbnZlcnRlciIpKSRzYXQpIAoKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQUkUiKSkkc2F0LCBzdWJzZXQoZmlsdGVyKGNvbnZUX3BhaXJlZF9QUCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQT1NUIikpJHNhdCwgc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWRfUFAsIFRpbWUgPT0gIlBPU1QiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWRfUFAsIFBoZW5vdHlwZSA9PSAibG93IGNvbnZlcnRlciIpKSRzYXQsIHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBQaGVub3R5cGUgPT0gImxvdyBjb252ZXJ0ZXIiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBQaGVub3R5cGUgPT0gImhpZ2ggY29udmVydGVyIikpJHNhdCwgc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWRfUFAsIFBoZW5vdHlwZSA9PSAiaGlnaCBjb252ZXJ0ZXIiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCgpzYXRfc3Rvb2wubWVsdCA8LSBtZWx0KGNvbnZUX3BhaXJlZF9QUCwgaWQudmFycyA9IGMoJ1BoZW5vdHlwZScsJ1RpbWUnKSwgbWVhc3VyZS52YXJzID0gYygnc2F0JykpCnNhdF9zdG9vbC5tZWx0JFRpbWUgPC1mYWN0b3Ioc2F0X3N0b29sLm1lbHQkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKc2F0X3N0b29sLm1lbHQgPC0gZHBseXI6OnJlbmFtZShzYXRfc3Rvb2wubWVsdCwgRkE9dmFyaWFibGUpCnNhdF9zdG9vbC5tZWx0IDwtIGRwbHlyOjpyZW5hbWUoc2F0X3N0b29sLm1lbHQsIENvbmNlbnRyYXRpb249dmFsdWUpCgpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvY29udmVydGVyLnNhdC5wZGYiLHdpZHRoPTgsIGhlaWdodD0xMCkKZ2dwbG90KGZpbHRlcihzYXRfc3Rvb2wubWVsdCwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9UGhlbm90eXBlLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IFBoZW5vdHlwZSkpICtmYWNldF9ncmlkKC5+IFRpbWUpICsKICB4bGFiICgnQ29udmVydGVyIHR5cGUnKSsgeWxhYiAoJ0dlc8OkdHRpZ3RlIEZldHRzw6R1cmVua29uemVudHJhdGlvbiBbbm1vbC9nXSAnKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJoaWdoIGNvbnZlcnRlciIsICJsb3cgY29udmVydGVyIiksIHZhbHVlcyA9IGMoInNlYXNoZWxsNCIsICJzZWFzaGVsbDIiKSkrCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gLjcsIGx3ZD0wLjYpICsgdGhlbWVfY2xhc3NpYygpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gRiwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoImxvdyBjb252ZXJ0ZXIiKSkpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQpkZXYub2ZmKCkKCmBgYAoKVG90YWwgRkEKCmBgYHtyfQp0b3RhbF9zdG9vbC5tZWx0IDwtIG1lbHQoY29udlRfcGFpcmVkX1BQLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywnVGltZScpLCBtZWFzdXJlLnZhcnMgPSBjKCd0b3RhbCcpKQp0b3RhbF9zdG9vbC5tZWx0IDwtIHJlbmFtZSh0b3RhbF9zdG9vbC5tZWx0LCBGQT12YXJpYWJsZSkKdG90YWxfc3Rvb2wubWVsdCA8LSByZW5hbWUodG90YWxfc3Rvb2wubWVsdCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCgpnZ3Bsb3QoZmlsdGVyKHRvdGFsX3N0b29sLm1lbHQsICFUaW1lPT0iRk9MTE9XLVVQIiAmICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gRkEpKSArCiAgZmFjZXRfZ3JpZCgufiBQaGVub3R5cGUpICsKICB4bGFiICgnVGltZSBQb2ludCcpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoInRvdGFsIGZhdHR5IGFjaWRzIiksIHZhbHVlcyA9IGMoInN0ZWVsYmx1ZTIiKSkrCiAgZ2VvbV9ib3hwbG90KCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBULCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpCgpnZ3Bsb3QoZmlsdGVyKHRvdGFsX3N0b29sLm1lbHQsICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSkpICsKICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICB4bGFiICgnQ29udmVydGVyIHR5cGUnKSsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvZ10gJykgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygidG90YWwgZmF0dHkgYWNpZCIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogIGdlb21fYm94cGxvdCgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gRiwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoImhpZ2ggY29udmVydGVyIiwgImxvdyBjb252ZXJ0ZXIiKSkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQpgYGAKCmVpbmZhY2ggdW5nZXNhZXR0aWd0CgpgYGB7cn0KbW9uby51bnNhdF9zdG9vbC5tZWx0IDwtIG1lbHQoY29udlRfcGFpcmVkX1BQLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywnVGltZScpLCBtZWFzdXJlLnZhcnMgPSBjKCdtb25vLnVuc2F0JykpCm1vbm8udW5zYXRfc3Rvb2wubWVsdCA8LSByZW5hbWUobW9uby51bnNhdF9zdG9vbC5tZWx0LCBGQT12YXJpYWJsZSkKbW9uby51bnNhdF9zdG9vbC5tZWx0IDwtIHJlbmFtZShtb25vLnVuc2F0X3N0b29sLm1lbHQsIENvbmNlbnRyYXRpb249dmFsdWUpCgoKZ2dwbG90KGZpbHRlcihtb25vLnVuc2F0X3N0b29sLm1lbHQsICFUaW1lPT0iRk9MTE9XLVVQIiAmICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gRkEpKSArCiAgZmFjZXRfZ3JpZCgufiBQaGVub3R5cGUpICsKICB4bGFiICgnVGltZSBQb2ludCcpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoIm1vbm8gdW5zYXR1cmF0ZWQgZmF0dCBhY2lkcyIpLCB2YWx1ZXMgPSBjKCJjb3JhbDIiKSkrCiAgZ2VvbV9ib3hwbG90KCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBULCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpCgpnZ3Bsb3QoZmlsdGVyKG1vbm8udW5zYXRfc3Rvb2wubWVsdCwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9UGhlbm90eXBlLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgK2ZhY2V0X2dyaWQoLn4gVGltZSkgKwogIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9nXSAnKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJtb25vIHVuc2F0dXJhdGVkIGZhdHR5IGFjaWQiKSwgdmFsdWVzID0gYygiY29yYWwyIikpKwogIGdlb21fYm94cGxvdCgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gRiwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoImhpZ2ggY29udmVydGVyIiwgImxvdyBjb252ZXJ0ZXIiKSkpCgpgYGAKCnp3ZWlmYWNoIHVuZ2VzYWV0dGlndCArIHdpbGNveG9uIHRlc3QKaW4gQXJiZWl0CgpgYGB7cn0KZGkudW5zYXRfc3Rvb2wubWVsdCA8LSBtZWx0KGNvbnZUX3BhaXJlZF9QUCwgaWQudmFycyA9IGMoJ1BoZW5vdHlwZScsJ1RpbWUnKSwgbWVhc3VyZS52YXJzID0gYygnZGkudW5zYXQnKSkKZGkudW5zYXRfc3Rvb2wubWVsdCA8LSByZW5hbWUoZGkudW5zYXRfc3Rvb2wubWVsdCwgRkE9dmFyaWFibGUpCmRpLnVuc2F0X3N0b29sLm1lbHQgPC0gcmVuYW1lKGRpLnVuc2F0X3N0b29sLm1lbHQsIENvbmNlbnRyYXRpb249dmFsdWUpCgoKZ2dwbG90KGZpbHRlcihkaS51bnNhdF9zdG9vbC5tZWx0LCAhVGltZT09IkZPTExPVy1VUCIgJiAhUGhlbm90eXBlPT0ibm90IGNsYXNzaWZpZWQiKSxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIGZhY2V0X2dyaWQoLn4gUGhlbm90eXBlKSArCiAgeGxhYiAoJ1RpbWUgUG9pbnQnKSsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJkaXVuc2F0dXJhdGVkIGZhdHR5IGFjaWQiKSwgdmFsdWVzID0gYygic2Vhc2hlbGw0IikpKwogIGdlb21fYm94cGxvdCgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKQoKCm1lYW4oc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWRfUFAsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gImhpZ2ggY29udmVydGVyIikpJGRpLnVuc2F0KSAKCnNkKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJoaWdoIGNvbnZlcnRlciIpKSRkaS51bnNhdCkgCgptZWFuKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAiaGlnaCBjb252ZXJ0ZXIiKSkkZGkudW5zYXQpIAoKc2Qoc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWRfUFAsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJoaWdoIGNvbnZlcnRlciIpKSRkaS51bnNhdCkgCgoKbWVhbihzdWJzZXQoZmlsdGVyKGNvbnZUX3BhaXJlZF9QUCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAibG93IGNvbnZlcnRlciIpKSRkaS51bnNhdCkgCgpzZChzdWJzZXQoZmlsdGVyKGNvbnZUX3BhaXJlZF9QUCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAibG93IGNvbnZlcnRlciIpKSRkaS51bnNhdCkgCgptZWFuKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAibG93IGNvbnZlcnRlciIpKSRkaS51bnNhdCkgCgpzZChzdWJzZXQoZmlsdGVyKGNvbnZUX3BhaXJlZF9QUCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImxvdyBjb252ZXJ0ZXIiKSkkZGkudW5zYXQpIAoKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQUkUiKSkkZGkudW5zYXQsIHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQUkUiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWRfUFAsIFRpbWUgPT0gIlBPU1QiKSkkZGkudW5zYXQsIHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBUaW1lID09ICJQT1NUIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBQaGVub3R5cGUgPT0gImxvdyBjb252ZXJ0ZXIiKSkkZGkudW5zYXQsIHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkX1BQLCBQaGVub3R5cGUgPT0gImxvdyBjb252ZXJ0ZXIiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGNvbnZUX3BhaXJlZF9QUCwgUGhlbm90eXBlID09ICJoaWdoIGNvbnZlcnRlciIpKSRkaS51bnNhdCwgc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWRfUFAsIFBoZW5vdHlwZSA9PSAiaGlnaCBjb252ZXJ0ZXIiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9jb252ZXJ0ZXIudW5zYXQucGRmIix3aWR0aD04LCBoZWlnaHQ9MTApCmdncGxvdChmaWx0ZXIoZGkudW5zYXRfc3Rvb2wubWVsdCwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9UGhlbm90eXBlLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IFBoZW5vdHlwZSkpICsKICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICB4bGFiICgnQ29udmVydGVyIHR5cGUnKSsgeWxhYiAoJ1p3ZWlmYWNoIHVuZ2Vzw6R0dGlndGUgRmV0dHPDpHVyZW5rb256ZW50cmF0aW9uIFtubW9sL2ddICcpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoImhpZ2ggY29udmVydGVyIiwgImxvdyBjb252ZXJ0ZXIiKSwgdmFsdWVzID0gYygic2Vhc2hlbGw0IiwgInNlYXNoZWxsMiIpKSsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAuNywgbHdkPTAuNikgKyB0aGVtZV9jbGFzc2ljKCkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiaGlnaCBjb252ZXJ0ZXIiLCAibG93IGNvbnZlcnRlciIpKSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmRldi5vZmYoKQoKYGBgCgpPbWVnYTYvT21lZ2EzLXJhdGlvCgpgYGB7cn0Kc2F0X3N0b29sLm9tZWdhIDwtIG1lbHQoY29udlRfcGFpcmVkX1BQLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywnVGltZScpLCBtZWFzdXJlLnZhcnMgPSBjKCdyYXRpbycpKQoKc2F0X3N0b29sLm9tZWdhJFRpbWUgPC1mYWN0b3Ioc2F0X3N0b29sLm9tZWdhJFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIikpCgpzYXRfc3Rvb2wub21lZ2EgPC0gZHBseXI6OnJlbmFtZShzYXRfc3Rvb2wub21lZ2EsIEZBPXZhcmlhYmxlKQpzYXRfc3Rvb2wub21lZ2EgPC0gZHBseXI6OnJlbmFtZShzYXRfc3Rvb2wub21lZ2EsIENvbmNlbnRyYXRpb249dmFsdWUpCgoKZ2dwbG90KGZpbHRlcihzYXRfc3Rvb2wub21lZ2EsICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBQaGVub3R5cGUpKSArCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSArCiAgeGxhYiAoJ0NvbnZlcnRlciB0eXBlJykrIHlsYWIgKCdHZXPDpHR0aWd0ZSBGZXR0c8OkdXJlbmtvbnplbnRyYXRpb24gW25tb2wvZ10gJykgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiaGlnaCBjb252ZXJ0ZXIiLCAibG93IGNvbnZlcnRlciIpLCB2YWx1ZXMgPSBjKCJzZWFzaGVsbDQiLCAic2Vhc2hlbGwyIikpKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IC43LCBsd2Q9MC42KSArIHRoZW1lX2NsYXNzaWMoKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJsb3cgY29udmVydGVyIiwgImhpZ2ggY29udmVydGVyIikpKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0wLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKYGBgCgptZWhyIGFscyB6d2VpZmFjaCB1bmdlc2FldHRpZ3QKCmBgYHtyfQptb3JlLjIudW5zYXRfc3Rvb2wubWVsdCA8LSBtZWx0KGNvbnZUX3BhaXJlZF9QUCwgaWQudmFycyA9IGMoJ1BoZW5vdHlwZScsJ1RpbWUnKSwgbWVhc3VyZS52YXJzID0gYygnbW9yZS4yLnVuc2F0JykpCgptb3JlLjIudW5zYXRfc3Rvb2wubWVsdCA8LSByZW5hbWUobW9yZS4yLnVuc2F0X3N0b29sLm1lbHQsIEZBPXZhcmlhYmxlKQptb3JlLjIudW5zYXRfc3Rvb2wubWVsdCA8LSByZW5hbWUobW9yZS4yLnVuc2F0X3N0b29sLm1lbHQsIENvbmNlbnRyYXRpb249dmFsdWUpCgoKZ2dwbG90KGZpbHRlcihtb3JlLjIudW5zYXRfc3Rvb2wubWVsdCwgIVRpbWU9PSJGT0xMT1ctVVAiICYgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9VGltZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSkpICsKICBmYWNldF9ncmlkKC5+IFBoZW5vdHlwZSkgKwogIHhsYWIgKCdUaW1lIFBvaW50JykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiPiAyIHVuc2F0dXJhdGVkIiksIHZhbHVlcyA9IGMoImJyb3duNCIpKSsKICBnZW9tX2JveHBsb3QoKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFQsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkKCmdncGxvdChmaWx0ZXIobW9yZS4yLnVuc2F0X3N0b29sLm1lbHQsICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSkpICsKICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICB4bGFiICgnQ29udmVydGVyIHR5cGUnKSsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvZ10gJykgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiPiAyIHVuc2F0dXJhdGVkIiksIHZhbHVlcyA9IGMoImJyb3duNCIpKSsKICBnZW9tX2JveHBsb3QoKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJoaWdoIGNvbnZlcnRlciIsICJsb3cgY29udmVydGVyIikpKQoKYGBgCkMxOAoKYGBge3J9CmMxOC4xOV9zdG9vbC5tZWx0IDwtIG1lbHQoY29udlRfcGFpcmVkX1BQLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywnVGltZScpLCBtZWFzdXJlLnZhcnMgPSBjKCdjMTguMTknKSkKCmMxOC4xOV9zdG9vbC5tZWx0IDwtIHJlbmFtZShjMTguMTlfc3Rvb2wubWVsdCwgRkE9dmFyaWFibGUpCmMxOC4xOV9zdG9vbC5tZWx0IDwtIHJlbmFtZShjMTguMTlfc3Rvb2wubWVsdCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCgpnZ3Bsb3QoZmlsdGVyKGMxOC4xOV9zdG9vbC5tZWx0LCAhVGltZT09IkZPTExPVy1VUCIgJiAhUGhlbm90eXBlPT0ibm90IGNsYXNzaWZpZWQiKSxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIGZhY2V0X2dyaWQoLn4gUGhlbm90eXBlKSArCiAgeGxhYiAoJ1RpbWUgUG9pbnQnKSsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCIxOC0xOSBjLWF0b21lcyIpLCB2YWx1ZXMgPSBjKCJ5ZWxsb3cyIikpKwogIGdlb21fYm94cGxvdCgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKQoKZ2dwbG90KGZpbHRlcihjMTguMTlfc3Rvb2wubWVsdCwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9UGhlbm90eXBlLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IEZBKSkgKwogIGZhY2V0X2dyaWQoLn4gVGltZSkgKwogIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9nXSAnKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCIxOC0xOSBjLWF0b21lcyIpLCB2YWx1ZXMgPSBjKCJ5ZWxsb3cyIikpKwogIGdlb21fYm94cGxvdCgpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gRiwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoImhpZ2ggY29udmVydGVyIiwgImxvdyBjb252ZXJ0ZXIiKSkpCgpgYGAKCjIuMyBBbHBoYS1EaXZlcnNpdGFldCB1bmQgRkFzClNoYW5ub24gdW5kIFNpbXBzb24KCkxhZGVuIHVuZCBmaWx0ZXJuIGRlciBNZXRhZGF0ZW4KCmBgYHtyfQptYXBfYWxwaGFkaXYgPC0gcmVhZC50YWJsZSgiL1VzZXJzL3N0dWRlbnQwNS9Eb3dubG9hZHMvbWVhbnNfYWxwaGFfZGl2LnR4dCIsIHNlcCA9ICdcdCcsIGNvbW1lbnQ9JycsaGVhZCA9IFRSVUUsIHJvdy5uYW1lcyA9IDEpCgpGQV9zdG9vbCA8LSByZWFkLnRhYmxlKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy9GYS5mZWNlcy4yLnR4dCIsIHNlcCA9ICdcdCcsIGNvbW1lbnQ9JycsCiAgICAgICAgICAgICAgICAgICAgICAgaGVhZD1UKQoKVmlldyhGQV9zdG9vbCkKCkZBX3N0b29sJFRpbWUgPC1mYWN0b3IoRkFfc3Rvb2wkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiLCAiRk9MTE9XLVVQIikpCgpGQV9zdG9vbCA8LSBGQV9zdG9vbFstYyg1ODo2NCksIF0KCnJvdy5uYW1lcyhGQV9zdG9vbCkgPC0gRkFfc3Rvb2wkU2FtcGxlSUQKCmBgYAoKU3luY2hvbmlzaWVyZW4gZGVyIERhdGVuc2V0cwoKYGBge3J9CmNvbW1vbi5pZHMuU3QgPC0gaW50ZXJzZWN0KHJvd25hbWVzKEZBX3N0b29sKSwgcm93bmFtZXMobWFwX2FscGhhZGl2KSkKY29tbW9uLmlkcy5TdCA8LSBpbnRlcnNlY3Qocm93Lm5hbWVzKEZBX3N0b29sKSwgcm93Lm5hbWVzKG1hcF9hbHBoYWRpdikpCgpGQV9zdG9vbCA8LSBGQV9zdG9vbFtjb21tb24uaWRzLlN0LF0KCm1hcF9hbHBoYWRpdiA8LSBtYXBfYWxwaGFkaXZbY29tbW9uLmlkcy5TdCxdCgpGQV9zdG9vbCRTaGFubm9uIDwtIG1hcF9hbHBoYWRpdiRTaGFubm9uCgpGQV9zdG9vbCRTaW1wc29uIDwtIG1hcF9hbHBoYWRpdiRTaW1wc29uCgpgYGAKCkxvb3AgS29ycmVsYXRpb24gU2hhbm5vbiB1bmQgRkFzCgpgYGB7cn0KY29ycl9jb2xuYW1lc19GQSA8LWNvbG5hbWVzKEZBX3N0b29sWyw3OjE4XSkKCmNvcnJfc3BlYXJtYW5fU2hhbm5vbl9GQSA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiB1bmlxdWUoY29ycl9jb2xuYW1lc19GQSkpIHsKCiAgdG1wIDwtIGZpbHRlcihGQV9zdG9vbCwgIWlzLm5hKGkpKQoKICB4ID0gYXMubWF0cml4KGFzLmRhdGEuZnJhbWUobGFwcGx5KHRtcFssaV0sIGFzLm51bWVyaWMpKSkKCiAgeSA9IHQoYXMubWF0cml4KHRtcCRTaGFubm9uKSApCgogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogCiAgeiA9IGFzLm1hdHJpeChhcy5kYXRhLmZyYW1lKGxhcHBseShzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXSxhcy5udW1lcmljKSkpCiAgCiAgdyA9IHQoYXMubWF0cml4KHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkU2hhbm5vbikpCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQoKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogCiAgciA9IGFzLm1hdHJpeChhcy5kYXRhLmZyYW1lKGxhcHBseShzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0sYXMubnVtZXJpYykpKQogIAogIHMgPSB0KGFzLm1hdHJpeChzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRTaGFubm9uKSkKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9TaGFubm9uX0ZBKSsxCiAKICBjb3JyX3NwZWFybWFuX1NoYW5ub25fRkFbbnJvdywiRGl2Il0gPSAiU2hhbm5vbiIKICAKICBjb3JyX3NwZWFybWFuX1NoYW5ub25fRkFbbnJvdywgImNvbHVtbiJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fU2hhbm5vbl9GQVtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1NoYW5ub25fRkFbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1NoYW5ub25fRkFbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1NoYW5ub25fRkFbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fU2hhbm5vbl9GQVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9TaGFubm9uX0ZBW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogCn0KCmNvcnJfc3BlYXJtYW5fU2hhbm5vbl9GQSRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fU2hhbm5vbl9GQSRwLnZhbHVlLG1ldGhvZCA9ICJCSCIsIG4gPSAxMikKCmNvcnJfc3BlYXJtYW5fU2hhbm5vbl9GQSRwLmFkanVzdGVkX1BSRSA8LXAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fU2hhbm5vbl9GQSRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDEyKQoKY29ycl9zcGVhcm1hbl9TaGFubm9uX0ZBJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1NoYW5ub25fRkEkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMTIpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1NoYW5ub25fRkEsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvdGFiZWxsZW4vU2hhbm5vbi5GQS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gU2hhbm5vbiB1bmQgRmFzIGRpZSBpbnRlcmVzc2FudGUgS29ycmVsYXRpb24gemVpZ2VuIAoKYGBge3J9CmdncGxvdChGQV9zdG9vbCwgYWVzKHg9dG90YWwsIHk9U2hhbm5vbikpICsgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdUb3RhbCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArCiAgeWxhYignU2hhbm5vbi1JbmRleCcpCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wsIHg9J3RvdGFsJywgeT0nU2hhbm5vbicsIGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdUb3RhbCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKSArCiAgZmFjZXRfd3JhcCh+VGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wsIHg9J3NhdCcsIHk9J1NoYW5ub24nLCBjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJyksIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnU2hhbm5vbi1JbmRleCcpICsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dzY2F0dGVyKEZBX3N0b29sLCB4PSdhbnRlaXNvJywgeT0nU2hhbm5vbicsIGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdBbnRlaXNvIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnU2hhbm5vbi1JbmRleCcpICsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dzY2F0dGVyKEZBX3N0b29sLCB4PSdjMjIuMjQnLCB5PSdTaGFubm9uJywgY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ2MgMjItMjQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdTaGFubm9uLUluZGV4JykgKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wsIHg9J2MyMC4yMScsIHk9J1NoYW5ub24nLCBjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJyksIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnYyAyMC0yMSBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKSArCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wsIHg9J2MxNC4xNycsIHk9J1NoYW5ub24nLCBjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJyksIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnYyAxNC0xNyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKSArCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdnc2NhdHRlcihGQV9zdG9vbCwgeD0nbGVzcy4xNCcsIHk9J1NoYW5ub24nLCBjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJyksIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnPCAxNCBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnU2hhbm5vbi1JbmRleCcpICsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dzY2F0dGVyKEZBX3N0b29sLCB4PSdtb3JlLjIudW5zYXQnLCB5PSdTaGFubm9uJywgY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJz4gMiB1bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKSArCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdnc2NhdHRlcihGQV9zdG9vbCwgeD0nZGkudW5zYXQnLCB5PSdTaGFubm9uJywgY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0RpdW5zYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdTaGFubm9uLUluZGV4JykgKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wsIHg9J3NhdCcsIHk9J1NoYW5ub24nLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdTaGFubm9uLUluZGV4JykKCmdnc2NhdHRlcihGQV9zdG9vbCwgeD0nZGkudW5zYXQnLCB5PSdTaGFubm9uJywgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnRGl1bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKQoKCmdnc2NhdHRlcihGQV9zdG9vbCwgeD0nbW9yZS4yLnVuc2F0JywgeT0nU2hhbm5vbicsICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJz4gMiB1bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKQoKCmdnc2NhdHRlcihGQV9zdG9vbCwgeD0nYzIwLjIxJywgeT0nU2hhbm5vbicsICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ2MyMC0yMSBjIGF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnU2hhbm5vbi1JbmRleCcpCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wsIHg9J2MyMi4yNCcsIHk9J1NoYW5ub24nLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdjMjItMjQgYyBhdG9tcyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKQoKCmBgYAoKaW4gZGVyIEFyYmVpdApUb3RhbCBGQQoKYGBge3J9CnBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9TaGFubm9uLnRvdGFsRkEucGRmIix3aWR0aD04LCBoZWlnaHQ9MTApCmdnc2NhdHRlcihGQV9zdG9vbCwgeD0ndG90YWwnLCB5PSdTaGFubm9uJywgIGFkZCA9ICdyZWcubGluZScsY29sb3IgPSAiZ3JleTU5IixmaWxsID0gImxpZ2h0Z3JheSIsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLGNvci5jb2VmLmNvb3JkID0gYygwLDcpLCBjb3IuY29lZi5zaXplID0gOCwgeGxhYj0gJ0dlc2FtdGUgRmV0dHPDpHVyZW5rb256ZW50cmF0aW9uZW4gW25tb2wvZ10nLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIGdlb21fcG9pbnQoY29sb3I9J2JsYWNrJywgc2l6ZT0yLjUpCmRldi5vZmYoKQoKYGBgCgpLb3JyZWxhdGlvbiB6d2lzY2hlbiBTaGFubm9uIHVuZCBLZXR0ZW5sYWVuZ2UKTGFkZW4gZGVyIE1ldGFkYXRlbgoKYGBge3J9CkZBX3N0b29sLnNoIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL0RCIHNoYW5ub24udHh0Iiwgc2VwID0gJ1x0JywgY29tbWVudD0nJywKICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkPVQpCkZBX3N0b29sX3NoX3ByIDwtIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuc2gsICFUaW1lID09IlBPU1QiKSkKRkFfc3Rvb2xfc2hfcG8gPC0gc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5zaCwgIVRpbWUgPT0iUFJFIikpCmBgYAoKUGxvdHRlbiBkZXIgRGF0ZW4KCmBgYHtyfQpGQV9zdG9vbF9zaF9wciRTaGFubm9uIDwtIGFzLmRpc2NyZXRlKEZBX3N0b29sX3NoX3ByJFNoYW5ub24pCkZBX3N0b29sX3NoX3ByJENvbmNlbnRyYXRpb24gPC0gYXMuZGlzY3JldGUoRkFfc3Rvb2xfc2hfcHIkQ29uY2VudHJhdGlvbikKCmdnc2NhdHRlcihGQV9zdG9vbF9zaF9wciwgeD0nQ29uY2VudHJhdGlvbicsIHk9J1NoYW5ub24nLGNvbG9yID0gJ0RCJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicsJ3N0ZWVsYmx1ZScpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBULCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdTaGFubm9uIEluZGV4JykrCiAgZmFjZXRfZ3JpZCgufiBEQiwgc2NhbGVzPSJmcmVlIikrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIoRkFfc3Rvb2xfc2hfcG8sIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdTaGFubm9uJyxjb2xvciA9ICdEQicsICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFQsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPSBjKDI1MCwgNykseGxhYj0gJ0NvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1NoYW5ub24gSW5kZXgnKSsKICBmYWNldF9ncmlkKC5+IERCLCBzY2FsZXM9ImZyZWUiKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKYGBgCgpMb29wIFNpbXBzb24gdW5kIGFsbGUgRkFzCgpgYGB7cn0KY29ycl9zcGVhcm1hbl9TaW1wc29uX0ZBIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHVuaXF1ZShjb3JyX2NvbG5hbWVzX0ZBKSkgewogIAogIHRtcCA8LSBmaWx0ZXIoRkFfc3Rvb2wsICFpcy5uYShpKSkKCiAgeCA9IGFzLm1hdHJpeChhcy5kYXRhLmZyYW1lKGxhcHBseSh0bXBbLGldLCBhcy5udW1lcmljKSkpCgogIHkgPSB0KGFzLm1hdHJpeCh0bXAkU2ltcHNvbikpCgogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQoKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCgogIHogPSBhcy5tYXRyaXgoYXMuZGF0YS5mcmFtZShsYXBwbHkoc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0sYXMubnVtZXJpYykpKQogIAogIHcgPSB0KGFzLm1hdHJpeCAoc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRTaW1wc29uKSkKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCgogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCgogIHIgPSBhcy5tYXRyaXgoYXMuZGF0YS5mcmFtZShsYXBwbHkoc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldLGFzLm51bWVyaWMpKSkKICAKICBzID0gdChhcy5tYXRyaXgoc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkU2ltcHNvbikpCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fU2ltcHNvbl9GQSkrMQoKICBjb3JyX3NwZWFybWFuX1NpbXBzb25fRkFbbnJvdywiRGl2Il0gPSAiU2ltcHNvbiIKICAKICBjb3JyX3NwZWFybWFuX1NpbXBzb25fRkFbbnJvdywgImNvbHVtbiJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fU2ltcHNvbl9GQVtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1NpbXBzb25fRkFbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1NpbXBzb25fRkFbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1NpbXBzb25fRkFbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fU2ltcHNvbl9GQVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9TaW1wc29uX0ZBW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAp9CgoKY29ycl9zcGVhcm1hbl9TaW1wc29uX0ZBJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9TaW1wc29uX0ZBJHAudmFsdWUsbWV0aG9kID0gIkJIIiwgbiA9IDEyKQoKY29ycl9zcGVhcm1hbl9TaW1wc29uX0ZBJHAuYWRqdXN0ZWRfUFJFIDwtcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9TaW1wc29uX0ZBJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMTIpCgpjb3JyX3NwZWFybWFuX1NpbXBzb25fRkEkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fU2ltcHNvbl9GQSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAxMikKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fU2ltcHNvbl9GQSwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy90YWJlbGxlbi9TaW1wc29uLkZBLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCgpjb3JyX3NpZ19TaW1wc29uX0ZBIDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX1NpbXBzb25fRkEsIHAuYWRqdXN0ZWQgPCAwLjA1IHwgcC5hZGp1c3RlZF9QUkUgPCAwLjUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjUgfCBwLmFkanVzdGVkX0ZVIDwgMC41KQoKYGBgCgpQbG90dGVuIGRlciBNZXRhZGF0ZW4gU2ltcHNvbiB1bmQgaW50ZXJlc3NhbnRlIEZBcwoKYGBge3J9Cmdnc2NhdHRlcihGQV9zdG9vbCwgeD0ndG90YWwnLCB5PSdTaGFubm9uJywgY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpLAogICAgICAgICAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZj0gVFJVRSwgY29yLmNvZWYuY29vcmQgPSBjKDAsMC45OTgpLAogICAgICAgICAgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZHMgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnU2ltcHNvbi1JbmRleCcpICsgCiAgZmFjZXRfd3JhcCh+VGltZSwgc2NhbGVzID0gImZyZWVfeCIpCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wsIHg9J3RvdGFsJywgeT0nU2ltcHNvbicsIGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSwKICAgICAgICAgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgY29yLmNvZWY9IFRSVUUsIGNvci5jb2VmLmNvb3JkID0gYygwLDAuOTk4KSwKICAgICAgICAgIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnVG90YWwgZmF0dHkgYWNpZHMgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnU2ltcHNvbi1JbmRleCcpICsgCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdnc2NhdHRlcihGQV9zdG9vbCwgeD0nc2F0JywgeT0nU2ltcHNvbicsCiAgICAgICAgICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIGNvci5jb2VmPSBUUlVFLCBjb3IuY29lZi5jb29yZCA9IGMoMCwwLjk5OCksCiAgICAgICAgICBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1NhdHVyYXRlZCBmYXR0eSBhY2lkcyBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdTaW1wc29uLUluZGV4JykgCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wsIHg9J3RvdGFsJywgeT0nU2ltcHNvbicsCiAgICAgICAgICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIGNvci5jb2VmPSBUUlVFLCBjb3IuY29lZi5jb29yZCA9IGMoMCwwLjk5OCksCiAgICAgICAgICBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1RvdGFsIGZhdHR5IGFjaWRzIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1NpbXBzb24tSW5kZXgnKSAKIAoKYGBgCgoyLjQgS29ycmVsYXRpb25zYW5hbHlzZW4gendpc2NoZW4gVGF4YSB1bmQgZGVuIEZBcwoKTGFkZW4gdW5kIGZpbHRlcm4gZGVyIE1ldGFkYXRlbiwgUHlsdW0gdW5kIEdlbnVzIGxldmVsIHNldHplbiwgRGF0ZW4gc2ljaGVybgoKYGBge3J9CnJlbGFiX21lYW5zIDwtIHJlYWQudGFibGUoJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3JlbGF0aXZlIGFidW5kYW5jZS9yZWxhYl9tZWFuc19wZXJfdGltZXBvaW50LnR4dCcsIHNlcCA9J1x0JywgY29tbWVudD0nJywgaGVhZD1UKQoKCnJlbGFiX21lYW5zX21lbHQgPC0gbWVsdChyZWxhYl9tZWFucywgaWQ9YygnUHJvYmFuZCcsICdUaW1lJykpCgpyZWxhYl9tZWFuc19tZWx0IDwtIGRwbHlyOjpyZW5hbWUocmVsYWJfbWVhbnNfbWVsdCwgVGF4YT12YXJpYWJsZSkKCnJlbGFiX21lYW5zX21lbHQgPC0gZHBseXI6OnJlbmFtZShyZWxhYl9tZWFuc19tZWx0LCBSZWxhdGl2ZV9BYnVuZGFuY2U9dmFsdWUpCgpyZWxhYl9waHlsdW0gPC0gc3Vic2V0KHJlbGFiX21lYW5zX21lbHQsICFncmVwbCgiZ19ffGZfX3xvX198Y19fIiwgcmVsYWJfbWVhbnNfbWVsdCRUYXhhKSkKCnJlbGFiX3BoeWx1bSA8LSBzdWJzZXQocmVsYWJfcGh5bHVtLCAhZ3JlcGwoImtfX0FyY2hhZWEiLCByZWxhYl9waHlsdW0kVGF4YSkpCgpyZWxhYl9waHlsdW0kVGltZSA8LSBmYWN0b3IocmVsYWJfcGh5bHVtJFRpbWUsIGxldmVscz1jKCdQUkUnLCdQT1NUJywnRk9MTE9XLVVQJykpCgpyZWxhYl9waHlsdW1fc3ByZWFkIDwtIHNwcmVhZChyZWxhYl9waHlsdW0sIFRheGEsIFJlbGF0aXZlX0FidW5kYW5jZSwgc2VwID0gTlVMTCkKCnJlbGFiX2dlbnVzIDwtIHN1YnNldChyZWxhYl9tZWFuc19tZWx0LCBncmVwbCgiZ19fIiwgcmVsYWJfbWVhbnNfbWVsdCRUYXhhKSkKCnJlbGFiX2dlbnVzIDwtIHN1YnNldChyZWxhYl9nZW51cywgIWdyZXBsKCJrX19BcmNoYWVhIiwgcmVsYWJfZ2VudXMkVGF4YSkpCgpyZWxhYl9nZW51cyRUaW1lIDwtIGZhY3RvcihyZWxhYl9nZW51cyRUaW1lLCBsZXZlbHMgPSBjKCdQUkUnLCdQT1NUJywnRk9MTE9XLVVQJykpCgpyZWxhYl9nZW51c19zcHJlYWQgPC0gc3ByZWFkKHJlbGFiX2dlbnVzLCBUYXhhLCBSZWxhdGl2ZV9BYnVuZGFuY2UsIHNlcCA9IE5VTEwpCgp3cml0ZS50YWJsZShyZWxhYl9waHlsdW1fc3ByZWFkLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3JlbGF0aXZlIGFidW5kYW5jZS9yZWxhYl9waHlsdW0udHh0Jywgc2VwPSAiXHQiLCBjb2wubmFtZXMgPSBUUlVFLCByb3cubmFtZXMgPSBGQUxTRSkKCndyaXRlLnRhYmxlKHJlbGFiX2dlbnVzX3NwcmVhZCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9yZWxhdGl2ZSBhYnVuZGFuY2UvcmVsYWJfZ2VudXMudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLCByb3cubmFtZXMgPSBGQUxTRSkKCnJlbGFiX3BoeWx1bV9zcHJlYWQgPC0gcmVhZC50YWJsZSgiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvcmVsYXRpdmUgYWJ1bmRhbmNlL3JlbGFiX3BoeWx1bS50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZD1UKQpyZWxhYl9nZW51c19zcHJlYWQgPC0gIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3JlbGF0aXZlIGFidW5kYW5jZS9yZWxhYl9nZW51cy50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZD1UKQpgYGAKClN5bmNob25pc2llcmVuIGRlciBNZXRhZGF0ZW5zZXRzIHVuZCBMYWRlbiBkZXIgRkEtTWV0YWRhdGVuCgpgYGB7cn0KcmVsYWJfcGh5bHVtX0lEIDwtIHJlbGFiX3BoeWx1bV9zcHJlYWQKCnJlbGFiX3BoeWx1bV9JRCA8LSBtdXRhdGUocmVsYWJfcGh5bHVtX0lELCBTYW1wbGVJRCA9IHBhc3RlKFByb2JhbmQsIFRpbWUsc2VwPSIuIikpCgpyb3cubmFtZXMocmVsYWJfcGh5bHVtX0lEKSA8LSByZWxhYl9waHlsdW1fSUQkU2FtcGxlSUQKCnJlbGFiX2dlbnVzX0lEIDwtIHJlbGFiX2dlbnVzX3NwcmVhZAoKcmVsYWJfZ2VudXNfSUQgPC0gbXV0YXRlKHJlbGFiX2dlbnVzX0lELCBTYW1wbGVJRCA9IHBhc3RlKFByb2JhbmQsIFRpbWUsIHNlcCA9Ii4iKSkKCnJvdy5uYW1lcyhyZWxhYl9nZW51c19JRCkgPC0gcmVsYWJfZ2VudXNfSUQkU2FtcGxlSUQKCkZBX3N0b29sIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL0ZhLmZlY2VzLjIudHh0Iiwgc2VwID0gJ1x0JywgY29tbWVudD0nJywKICAgICAgICAgICAgICAgICAgICAgICBoZWFkPVQpCgpGQV9zdG9vbCRUaW1lIDwtZmFjdG9yKEZBX3N0b29sJFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIiwgIkZPTExPVy1VUCIpKQoKCkZBX3N0b29sIDwtIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wsICFUaW1lID09ICJGT0xMT1ctVVAiKSkKCkZBX3N0b29sIDwtIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wsICFQcm9iYW5kID09ICIzMUtFIiwgIVByb2JhbmQgPT0gIjM0V0YiLAogICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICFQcm9iYW5kID09ICI0NUdMIiwgIVByb2JhbmQgPT0gIjQ5UkoiLCAhUHJvYmFuZCA9PSAiNTRTTCIsICFQcm9iYW5kID09ICI3NFNBIikpCgpGQV9zdG9vbCA8LSBtdXRhdGUoRkFfc3Rvb2wsIFNhbXBsZUlEMSA9IHBhc3RlKFByb2JhbmQsIFRpbWUsIHNlcCA9ICIuIikpCgpyb3cubmFtZXMoRkFfc3Rvb2wpIDwtIEZBX3N0b29sJFNhbXBsZUlECgpjb21tb24uaWRzLnJlbGFiIDwtIGludGVyc2VjdChyb3duYW1lcyhGQV9zdG9vbCksIHJvd25hbWVzKHJlbGFiX3BoeWx1bV9JRCkpCgpGQV9zdG9vbCA8LSBGQV9zdG9vbFtjb21tb24uaWRzLnJlbGFiLF0KCnJlbGFiX3BoeWx1bV9JRCA8LSByZWxhYl9waHlsdW1fSURbY29tbW9uLmlkcy5yZWxhYixdCgpyZWxhYl9nZW51c19JRCA8LSByZWxhYl9nZW51c19JRFtjb21tb24uaWRzLnJlbGFiLF0KCndyaXRlLnRhYmxlKEZBX3N0b29sLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL0ZBIGZlY2FsL3JlbGF0aXZlIGFidW5kYW5jZS9GQV9zdG9vbF90b3RhbC50eHQnLCBzZXA9ICJcdCIsIGNvbC5uYW1lcyA9IFRSVUUsIHJvdy5uYW1lcyA9IEZBTFNFKQoKCmBgYAoKRXJzdGVsbGVuIGRlcyBQaHlsdW0tRGF0ZW5zZXRzIHVuZCBoaW56dWZ1ZWdlbiBkZXMgTG9nIHVuZCBQc2V1ZG9jb3VudHMgMC4wMDAwMQoKYGBge3J9CnBoeWx1bV9jb2xuYW1lcyA8LSBjb2xuYW1lcyhyZWxhYl9waHlsdW1fc3ByZWFkWywgYygzOjgpXSkKCnJlbGFiX3BoeWx1bV9JRCA8LSByZWxhYl9waHlsdW1fSURbLGMoMzo4KV0rIDAuMDAwMDEKCnJlbGFiX3BoeWx1bV9JRF9sb2cgPC0gbG9nMTAocmVsYWJfcGh5bHVtX0lEX2xvZykKCnBoeWx1bV9GQSA8LSBjYmluZChyZWxhYl9waHlsdW1fSUQsIEZBX3N0b29sWywgYygxOjE5KV0pCnBoeWx1bV9GQSRUaW1lIDwtIGZhY3RvcihwaHlsdW1fRkEkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmBgYAoKTG9vcCBmdWVyIEtvcnJlbGF0aW9uIHp3aXNjaGVuIGdlc2FldHRpZ3RlbiBGQSB1bmQgUGh5bHVtLUxldmVsCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX3NhdCA8LSBmaWx0ZXIocGh5bHVtX0ZBLCAhaXMubmEoc2F0KSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdCA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBwaHlsdW1fY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9zYXQsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkc2F0CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkc2F0CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRzYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdCkrMQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdFtucm93LCJGQSJdIDwtICJzYXQiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fc2F0W25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXRbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXRbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fc2F0W25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXRbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXRbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fc2F0W25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fc2F0JHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fc2F0JHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkgCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXQkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fc2F0JHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXQkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdCRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCgpjb3JyX3NpZ19QaHlsdW1fc2F0IDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXQsIHAuYWRqdXN0ZWQgPCAwLjA1IHwgcC5hZGp1c3RlZF9QUkUgPCAwLjA1IHwgcC5hZGp1c3RlZF9QT1NUIDwgMC4wNSkKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy90YWJlbGxlbi9zYXQucGh5bHVtLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmBgYAoKUGxvdHRlbiBkZXIgZ2VzYWV0dGlndGVuIEZBIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYSwgeD1zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ1NhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSwgc2NhbGVzPSJmcmVlX3giKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J3NhdCcsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1Byb3Rlb2JhY3RlcmlhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSdzYXQnLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLGNvci5jb2VmLmNvb3JkID0gYygwLCAtMS43KSwgY29yLmNvZWYuc2l6ZSA9IDYsIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1Byb3Rlb2JhY3RlcmlhJykrCiAgCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0wLCBoanVzdD0xKSkKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J3NhdCcsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9YygyNTAsIC0xKSwgeGxhYj0gJ1NhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVmVycnVjb21pY3JvYmlhJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J3NhdCcsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMnLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID1jKDI1MCwgLTAuNzUpLCB4bGFiPSAnU2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCnN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIiwgbGFiZWwueCA9IDMsIGxhYmVsLnkgPSAzMCkKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSwgeD1zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ1NhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVmVycnVjb21pY3JvYmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLCB4PXNhdCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignU2F0dXJhdGVkIGZhdHR5IGFjaWQgIENvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEsIHg9c2F0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdTYXR1cmF0ZWQgZmF0dHkgYWNpZCAgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKYGBgCgppbiBBcmJlaXQKCmBgYHtyfQpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvc2F0LnZlcnJ1LnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSdzYXQnLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLGNvbG9yID0gImdyZXk1OSIsZmlsbCA9ICJsaWdodGdyYXkiLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJycsY29yLmNvZWYuc2l6ZSA9IDgseGxhYj0gJ0dlc8OkdHRpZ3RlIEZldHRzw6R1cmVua29uemVudHJhdGlvbmVuIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZXMgVm9ya29tbWVuIHBfX1ZlcnJ1Y29taWNyb2JpYSBbJV0nKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2VvbV9wb2ludChjb2xvcj0nYmxhY2snLCBzaXplPTIuNSkrCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKQogIGRldi5vZmYoKQogIAogIHBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9zYXQuYmFjdGVyb2lkZXRlcy5wZGYiLHdpZHRoPTgsIGhlaWdodD0xMCkKZ2dzY2F0dGVyKHBoeWx1bV9GQSwgeD0nc2F0JywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCdza3libHVlJywgJ29yY2hpZCcpLCAgYWRkID0gJ3JlZy5saW5lJywgc2l6ZSA9IDIuNSxjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPWMoMCwgLTAuOCksY29yLmNvZWYuc2l6ZSA9IDcsIHhsYWI9ICdHZXPDpHR0aWd0ZSBGZXR0c8OkdXJlbmtvbnplbnRyYXRpb25lbiBbbm1vbC9nXScsIHlsYWIgPSAnUmVsYXRpdmVzIFZvcmtvbW1lbiBwX19CYWN0ZXJvaWRldGVzIFslXScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpCmRldi5vZmYoKQoKcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL3Vuc2F0LmJhY3Rlcm9pZGV0ZXMucGRmIix3aWR0aD04LCBoZWlnaHQ9MTApCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J3Vuc2F0JywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCdza3libHVlJywgJ29yY2hpZCcpLCAgYWRkID0gJ3JlZy5saW5lJywgc2l6ZSA9IDIuNSxjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPWMoMCwgLTAuOCksY29yLmNvZWYuc2l6ZSA9IDcsIHhsYWI9ICdVbmdlc8OkdHRpZ3RlIEZldHRzw6R1cmVua29uemVudHJhdGlvbmVuIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZXMgVm9ya29tbWVuIHBfX0JhY3Rlcm9pZGV0ZXMgWyVdJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoKSkKZGV2Lm9mZigpCgpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvb21lZ2EzLmJhY3Rlcm9pZGV0ZXMubmV1LnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSdPbWVnYTMnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3NreWJsdWUnLCAnb3JjaGlkJyksICBhZGQgPSAncmVnLmxpbmUnLCBzaXplID0gMi41LGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9YygwLCAtMC44KSxjb3IuY29lZi5zaXplID0gNywgeGxhYj0gJ1VuZ2Vzw6R0dGlndGUgRmV0dHPDpHVyZW5rb256ZW50cmF0aW9uZW4gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlcyBWb3Jrb21tZW4gcF9fQmFjdGVyb2lkZXRlcyBbJV0nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKQpkZXYub2ZmKCkKCnBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9zYXQuYWtrZXJtYW5zaWEucGRmIix3aWR0aD04LCBoZWlnaHQ9MTApCmdnc2NhdHRlcihnZW51c19GQSwgeD0nc2F0JywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLGNvbG9yID0gImdyZXk1OSIsZmlsbCA9ICJsaWdodGdyYXkiLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoMCwgLTAuOCksY29yLmNvZWYuc2l6ZSA9IDgsIHhsYWI9ICdHZXPDpHR0aWd0ZSBGZXR0c8OkdXJlbmtvbnplbnRyYXRpb25lbiBbbm1vbC9nXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlcyBWb3Jrb21tZW4gZ19fQWtrZXJtYW5zaWEpJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdlb21fcG9pbnQoY29sb3I9J2dyZXk1MicpCmRldi5vZmYoKQpgYGAKCkxvb3AgZWluZmFjaCB1bmdlc2FldHRpZ3RlIEZBIHVuZCBQaHlsdW0tTGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9waHlsdW1fbW9uby51bnNhdCA8LSBmaWx0ZXIocGh5bHVtX0ZBLCAhaXMubmEobW9uby51bnNhdCkpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9tb25vLnVuc2F0IDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewoKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9tb25vLnVuc2F0LCAhaXMubmEoaSkpCiAgCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJG1vbm8udW5zYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCgogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJG1vbm8udW5zYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRtb25vLnVuc2F0CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fbW9uby51bnNhdCkrMQoKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9tb25vLnVuc2F0W25yb3csIkZBIl0gPC0gIm1vbm8udW5zYXQiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fbW9uby51bnNhdFtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fbW9uby51bnNhdFtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX21vbm8udW5zYXRbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fbW9uby51bnNhdFtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fbW9uby51bnNhdFtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX21vbm8udW5zYXRbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fbW9uby51bnNhdFtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX21vbm8udW5zYXQkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9tb25vLnVuc2F0JHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkgCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9tb25vLnVuc2F0JHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX21vbm8udW5zYXQkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX21vbm8udW5zYXQkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX21vbm8udW5zYXQkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfUGh5bHVtX21vbm8udW5zYXQgPC0gZmlsdGVyKGNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdCwgcC5hZGp1c3RlZCA8IDAuMDUgfCBwLmFkanVzdGVkX1BSRSA8IDAuMDUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjA1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9QaHlsdW1fbW9uby51bnNhdCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy90YWJlbGxlbi9tb25vLnVuc2F0LnBoeWx1bS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gdm9uIGVpbmZhY2ggdW5nZXNhZXR0aWd0ZW4gRkEgdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9CmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLCB4PW1vbm8udW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ01vbm91bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSdtb25vLnVuc2F0JywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ01vbm91bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLCB4PW1vbm8udW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ01vbm91bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSdtb25vLnVuc2F0JywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ01vbm91bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQWN0aW5vYmFjdGVyaWEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmBgYAoKTG9vcCB6d2VpZmFjaCB1bmdlc2FldHRpZ3RlbiBGQSB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX21vcmUuMi51bnNhdCA8LSBmaWx0ZXIocGh5bHVtX0ZBLCAhaXMubmEobW9yZS4yLnVuc2F0KSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX21vcmUuMi51bnNhdCA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBwaHlsdW1fY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9tb3JlLjIudW5zYXQsICFpcy5uYShpKSkKCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJG1vcmUuMi51bnNhdAoKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQoKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRtb3JlLjIudW5zYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRtb3JlLjIudW5zYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQoKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9tb3JlLjIudW5zYXQpKzEKCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fbW9yZS4yLnVuc2F0W25yb3csIkZBIl0gPC0gIj4gMiB1bnNhdCIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9tb3JlLjIudW5zYXRbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX21vcmUuMi51bnNhdFtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX21vcmUuMi51bnNhdFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9tb3JlLjIudW5zYXRbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX21vcmUuMi51bnNhdFtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX21vcmUuMi51bnNhdFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9tb3JlLjIudW5zYXRbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9tb3JlLjIudW5zYXQkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9tb3JlLjIudW5zYXQkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX21vcmUuMi51bnNhdCRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9tb3JlLjIudW5zYXQkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX21vcmUuMi51bnNhdCRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fbW9yZS4yLnVuc2F0JHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zaWdfUGh5bHVtX21vcmUuMi51bnNhdCA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9QaHlsdW1fbW9yZS4yLnVuc2F0LCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9tb3JlLjIudW5zYXQsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvdGFiZWxsZW4vbW9yZS4yLnVuc2F0LnBoeWx1bS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gdm9uIHp3ZWlmYWNoIHVuZ2VzYWV0dGlndGVuIEZBIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYSwgeD1tb3JlLjIudW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0RpdW5zYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcywgeD1tb3JlLjIudW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0RpdW5zYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J21vcmUuMi51bnNhdCcsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJz4gMiB1bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9GQSwgeD0nbW9yZS4yLnVuc2F0JywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnPiAyIHVuc2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYSwgeD1tb3JlLjIudW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0RpdW5zYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKYGBgCgpMb29wIHdlbmlnZXIgMTRDIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9waHlsdW1fbGVzcy4xNCA8LSBmaWx0ZXIocGh5bHVtX0ZBLCAhaXMubmEobGVzcy4xNCkpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9sZXNzLjE0IDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX2xlc3MuMTQsICFpcy5uYShpKSkKCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJGxlc3MuMTQKICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRsZXNzLjE0CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRsZXNzLjE0CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fbGVzcy4xNCkrMQoKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9sZXNzLjE0W25yb3csIkZBIl0gPC0gIjwgMTQgYyIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9sZXNzLjE0W25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9sZXNzLjE0W25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fbGVzcy4xNFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9sZXNzLjE0W25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9sZXNzLjE0W25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fbGVzcy4xNFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9sZXNzLjE0W25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fbGVzcy4xNCRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX2xlc3MuMTQkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX2xlc3MuMTQkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fbGVzcy4xNCRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fbGVzcy4xNCRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fbGVzcy4xNCRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCgpjb3JyX3NpZ19QaHlsdW1fbGVzcy4xNCA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9QaHlsdW1fbGVzcy4xNCwgcC5hZGp1c3RlZCA8IDAuMDUgfCBwLmFkanVzdGVkX1BSRSA8IDAuMDUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjA1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9QaHlsdW1fbGVzcy4xNCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy90YWJlbGxlbi9sZXNzLjE0LnBoeWx1bS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKCiBQbG90dGVuIEZBIG1pdCB3ZW5pZ2VyIGFscyAxNEMgYXRvbWUgdW5kIHBoeWx1bS1sZXZlbAogCmBgYHtyfQpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYSwgeD1sZXNzLjE0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCc8IDE0IGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKQoKZ2dzY2F0dGVyKHBoeWx1bV9GQSwgeD0nbGVzcy4xNCcsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMZXNzIDE0YyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUHJvdGVvYmFjdGVyaWEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmBgYAogCkxvb3AgQzE0LTE3IEZBIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9waHlsdW1fYzE0LjE3IDwtIGZpbHRlcihwaHlsdW1fRkEsICFpcy5uYShjMTQuMTcgKSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxNC4xNyAgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9waHlsdW1fYzE0LjE3ICwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRjMTQuMTcgCgogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkYzE0LjE3IAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkYzE0LjE3IAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE0LjE3ICkrMQoKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9jMTQuMTcgW25yb3csIkZBIl0gPC0gImMgMTQtMTciCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE0LjE3IFtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE0LjE3IFtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxNC4xNyBbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE0LjE3IFtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE0LjE3IFtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxNC4xNyBbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE0LjE3IFtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxNC4xNyAkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9jMTQuMTcgJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkgCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9jMTQuMTcgJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxNC4xNyAkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxNC4xNyAkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxNC4xNyAkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfUGh5bHVtX2MxNC4xNyA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE0LjE3LCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9jMTQuMTcsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvdGFiZWxsZW4vYzE0LjE3LnBoeWx1bS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gQzE0LTE3IEZBIHVuZCBwaHlsdW0tbGV2ZWwKIApgYGB7cn0KZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEsIHg9YzE0LjE3KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCcxNC0xNyBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J2MxNC4xNycsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdjIDE0LTE3IGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Qcm90ZW9iYWN0ZXJpYScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEsIHg9YzE0LjE3KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCc8IDE0LTE3IGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLCB4PWMxNC4xNykpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignPCAxNC0xNyBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLCB4PWMxNC4xNykpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignPCAxNC0xNyBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dzY2F0dGVyKHBoeWx1bV9GQSwgeD0nYzE0LjE3JywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9YygxNTAsIC0wLjcpLCB4bGFiPSAnYyAxNC0xNyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fRmlybWljdXRlcycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSdjMTQuMTcnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzJywgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID1jKDE1MCwgLTAuNyksIHhsYWI9ICdjIDE0LTE3IGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpgYGAKIAogTG9vcCBDMTggRkEgdW5kIHBoeWx1bS1sZXZlbAogCmBgYHtyfQpvcnJfbWFwX3BoeWx1bV9jMTguMTkgPC0gZmlsdGVyKHBoeWx1bV9GQSwgIWlzLm5hKGMxOCApKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE4LjE5ICA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBwaHlsdW1fY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9jMTguMTkgLCAhaXMubmEoaSkpCgogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRjMTgKICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCgogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJGMxOAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkYzE4CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE4LjE5ICkrMQoKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9jMTguMTkgW25yb3csIkZBIl0gPC0gImMgMTgtMTkiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE4LjE5IFtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE4LjE5IFtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxOC4xOSBbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE4LjE5IFtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE4LjE5IFtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxOC4xOSBbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE4LjE5IFtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxOC4xOSAkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9jMTguMTkgJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkgCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9jMTguMTkgJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxOC4xOSAkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxOC4xOSAkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX2MxOC4xOSAkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfUGh5bHVtX2MxOC4xOSA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9QaHlsdW1fYzE4LjE5LCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9jMTguMTksIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvdGFiZWxsZW4vYzE4LjE5LnBoeWx1bS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKIApQbG90dGVuIHZvbiBDMTggRkEgdW5kIHBoeWx1bS1sZXZlbAogCmBgYHtyfQpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYSwgeD1jMTguMTkpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJzE4LTE5IGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEsIHg9YzE4LjE5KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCc8IDE4LTE5IGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLCB4PWMxOC4xOSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignPCAxNC0xNyBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKHBoeWx1bV9GQSwgeD0nYzE4LjE5JywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdjIDE4LTE5IGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19WZXJydWNvbWljcm9iaWEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmBgYAogCkxvb3AgQzIwLTI0IHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9waHlsdW1fYzIwLjI0IDwtIGZpbHRlcihwaHlsdW1fRkEsICFpcy5uYShjMjAuMjQgKSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX2MyMC4yNCAgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9waHlsdW1fYzIwLjI0ICwgIWlzLm5hKGkpKQoKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkYzIwLjI0IAogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRjMjAuMjQgCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRjMjAuMjQgCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fYzIwLjI0ICkrMQoKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9jMjAuMjQgW25yb3csIkZBIl0gPC0gImMgMjAtMjQiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzIwLjI0IFtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzIwLjI0IFtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX2MyMC4yNCBbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzIwLjI0IFtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzIwLjI0IFtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX2MyMC4yNCBbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fYzIwLjI0IFtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX2MyMC4yNCRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX2MyMC4yNCRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpIAoKY29ycl9zcGVhcm1hbl9QaHlsdW1fYzIwLjI0JHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX2MyMC4yNCRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fYzIwLjI0JHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9jMjAuMjQkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfUGh5bHVtX2MyMC4yNCA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9QaHlsdW1fYzIwLjI0LCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9jMjAuMjQsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvdGFiZWxsZW4vYzIwLjI0LnBoeWx1bS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gdm9uIEMyMC0yNCB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEsIHg9YzIwLjIxKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCcyMC0yMSBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLCB4PWMyMC4yMSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignPCAxOC0xOSBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSwgeD1jMjAuMjEpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJzIwLTIxIGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J2MyMC4yMScsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnYyAyMC0yMSBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVmVycnVjb21pY3JvYmlhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcywgeD1jMjAuMjEpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJzIwLTIxIGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1RlbmVyaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dzY2F0dGVyKHBoeWx1bV9GQSwgeD0nYzIwLjIxJywgeT0na19fQmFjdGVyaWEucF9fVGVuZXJpY3V0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ2MgMjAtMjEgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1RlbmVyaWN1dGVzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKYGBgCgpMb29wIHRvdGFsIEZBIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9waHlsdW1fdG90YWwgPC0gZmlsdGVyKHBoeWx1bV9GQSwgIWlzLm5hKHRvdGFsICkpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV90b3RhbCAgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CiAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV90b3RhbCAsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkdG90YWwgCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCgogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSR0b3RhbCAKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJHRvdGFsIAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCgogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3RvdGFsICkrMQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3RvdGFsIFtucm93LCJGQSJdIDwtICJ0b3RhbCIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV90b3RhbCBbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3RvdGFsIFtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3RvdGFsIFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV90b3RhbCBbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3RvdGFsIFtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3RvdGFsIFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV90b3RhbCBbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV90b3RhbCAkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV90b3RhbCAkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKY29ycl9zcGVhcm1hbl9QaHlsdW1fdG90YWwgJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3RvdGFsICRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fdG90YWwgJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV90b3RhbCAkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfUGh5bHVtX3RvdGFsIDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX1BoeWx1bV90b3RhbCwgcC5hZGp1c3RlZCA8IDAuMDUgfCBwLmFkanVzdGVkX1BSRSA8IDAuMDUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjA1KQoKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX3RvdGFsLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL3RhYmVsbGVuL3RvdGFsLnBoeWx1bS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gdm9uIHRvdGFsIEZBIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYSwgeD10b3RhbCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYigndG90YWwgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dzY2F0dGVyKHBoeWx1bV9GQSwgeD0ndG90YWwnLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnVG90YWwgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSd0b3RhbCcsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdUb3RhbCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQWN0aW5vYmFjdGVyaWEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLCB4PXRvdGFsKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCd0b3RhbCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEsIHg9dG90YWwpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ3RvdGFsIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLCB4PXRvdGFsKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCd0b3RhbCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMsIHg9dG90YWwpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ3RvdGFsIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVGVuZXJpY3V0ZXMsIHg9dG90YWwpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ3RvdGFsIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J2MyMC4yMScsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdjIDIwLTIxIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19UZW5lcmljdXRlcycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKYGBgCgpMb29wIE9tZWdhMyB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX09tZWdhMyA8LSBmaWx0ZXIocGh5bHVtX0ZBLCAhaXMubmEoT21lZ2EzICkpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTMgIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX09tZWdhMyAsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkT21lZ2EzCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkT21lZ2EzCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRPbWVnYTMgCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTMgKSsxCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fT21lZ2EzIFtucm93LCJGQSJdIDwtICJPbWVnYTMiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fT21lZ2EzIFtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fT21lZ2EzIFtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhMyBbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fT21lZ2EzIFtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fT21lZ2EzIFtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhM1tucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTNbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTMkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTMkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhMyRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTMkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhMyRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fT21lZ2EzJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCmNvcnJfc2lnX1BoeWx1bV9PbWVnYTM8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9QaHlsdW1fT21lZ2EzLCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTMsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvdGFiZWxsZW4vT21lZ2EzLnBoeWx1bS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gT21lZ2EzIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLCB4PU9tZWdhMykpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcywgeD1PbWVnYTMpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLCB4PU9tZWdhMykpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCgpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvTGlub2xzw6R1cmUuYmFjdGVyb2lkZXRlcy5wZGYiLHdpZHRoPTgsIGhlaWdodD0xMCkKZ2dzY2F0dGVyKHBoeWx1bV9GQSwgeD0nT21lZ2EzJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnVGltZScsIGxhYmVsID0gJ1Byb2JhbmQnLHBhbGV0dGUgPSBjKCdza3libHVlJywgJ29yY2hpZCcpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygwLCAtMC45KSwgY29yLmNvZWYuc2l6ZSA9IDcseGxhYj0gJ0bDpGthbGUgYWxwaGEtTGlub2xlbnPDpHVyZSBLb256ZW50cmF0aW9uZW4gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZXMgVm9ya29tbWVuIHBfX0JhY3Rlcm9pZGV0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmRldi5vZmYoKQpgYGAKCkxvb3AgT21lZ2EgNiB1bmQgUGh5bHVtLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX09tZWdhNiA8LSBmaWx0ZXIocGh5bHVtX0ZBLCAhaXMubmEoT21lZ2E2ICkpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTYgIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX09tZWdhNiAsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkT21lZ2E2IAogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQoKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkT21lZ2E2IAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkT21lZ2E2IAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCgogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhNiApKzEKIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhNiBbbnJvdywiRkEiXSA8LSAiT21lZ2E2IgogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhNiBbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhNiBbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTYgW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhNiBbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhNiBbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTYgW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhNiBbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTYgJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fT21lZ2E2ICRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpIApjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTYgJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhNiAkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhNiAkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhNiAkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NpZ19QaHlsdW1fT21lZ2E2IDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX1BoeWx1bV9PbWVnYTYsIHAuYWRqdXN0ZWQgPCAwLjA1IHwgcC5hZGp1c3RlZF9QUkUgPCAwLjA1IHwgcC5hZGp1c3RlZF9QT1NUIDwgMC4wNSkKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX09tZWdhNiwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy90YWJlbGxlbi9PbWVnYTYucGh5bHVtLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCgpgYGAKClBsb3R0ZW4gb21lZ2E2IHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLCB4PU9tZWdhNikpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLCB4PU9tZWdhNikpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fRmlybWljdXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYSwgeD1PbWVnYTYpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVpYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLCB4PUxpbm9sc2FldXJlX2YpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVpYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSwgeD1MaW5vbHNhZXVyZV9mKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKYGBgCgpMb29wIG9tZWdhNi9vbWVnYTMtcmF0aW8gdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX3BoeWx1bV9yYXRpbyA8LSBmaWx0ZXIocGh5bHVtX0ZBLCAhaXMubmEocmF0aW8pKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fcmF0aW8gIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX3JhdGlvICwgIWlzLm5hKGkpKQogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRyYXRpbyAKICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkcmF0aW8gCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRyYXRpbyAKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhdGlvICkrMQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhdGlvIFtucm93LCJGQSJdIDwtICJyYXRpbyIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9yYXRpbyBbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhdGlvIFtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhdGlvIFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9yYXRpbyBbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhdGlvIFtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhdGlvIFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9yYXRpbyBbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9yYXRpbyAkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9yYXRpbyAkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhdGlvICRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9yYXRpbyAkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhdGlvICRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fcmF0aW8gJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCmNvcnJfc2lnX1BoeWx1bV9yYXRpbyA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9QaHlsdW1fcmF0aW8sIHAuYWRqdXN0ZWQgPCAwLjA1IHwgcC5hZGp1c3RlZF9QUkUgPCAwLjA1IHwgcC5hZGp1c3RlZF9QT1NUIDwgMC4wNSkKCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9yYXRpbywgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy90YWJlbGxlbi9yYXRpby5waHlsdW0udHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKCmBgYAoKUGxvdHRlbiB2b24gT21lZ2E2L29tZWdhMy1yYXRpbyB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEsIHg9cmF0aW8pKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdvbWVnYSA2L29tZWdhIDMgcmF0aW8gZmVjYWwnKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEsIHg9cmF0aW8pKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdvbWVnYSA2L29tZWdhIDMgcmF0aW8gZmVjYWwnKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcywgeD1yYXRpbykpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ29tZWdhIDYvb21lZ2EgMyByYXRpbyBmZWNhbCcpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEsIHg9cmF0aW8pKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdFUEEgaW50YWtlIFtnXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcywgeD1yYXRpbykpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ29tZWdhIDYvb21lZ2EgMyByYXRpbyBmZWNhbCcpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzLCB4PXJhdGlvKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignREhBIGludGFrZSBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQpgYGAKCkxvb3AgdW5nZXNhZXR0aWd0ZSBGQSB1bmQgUGh5bHVtLWxldmVsCgpgYGB7cn0KCmNvcnJfbWFwX3BoeWx1bV91bnNhdCA8LSBmaWx0ZXIocGh5bHVtX0ZBLCAhaXMubmEodW5zYXQpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQgIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX3Vuc2F0ICwgIWlzLm5hKGkpKQoKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkdW5zYXQgCgogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSR1bnNhdCAKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJHVuc2F0IAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQgKSsxCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQgW25yb3csIkZBIl0gPC0gInVuc2F0IgogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0IFtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQgW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQgW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0IFtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQgW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQgW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0IFtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0ICRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0ICRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpIAoKY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQgJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0ICRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQgJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdCAkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfUGh5bHVtX3Vuc2F0IDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdCwgcC5hZGp1c3RlZCA8IDAuMDUgfCBwLmFkanVzdGVkX1BSRSA8IDAuMDUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjA1KQoKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0LCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL3RhYmVsbGVuL3Vuc2F0LnBoeWx1bS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKCkFuYWx5c2VuIHp3aXNjaGVuIEZBIHVuZCBHZW51cy1sZXZlbApEYXRlbnNldHMgZmlsdGVybiB1bmQgaGluenVmdWVnZW4gdm9uIGxvZyB1bmQgcHNldWRvY291bnQgMC4wMDAwMQoKYGBge3J9CmdlbnVzX2NvbG5hbWVzIDwtIGNvbG5hbWVzKHJlbGFiX2dlbnVzX3NwcmVhZFssIGMoMzozMSldKQoKcmVsYWJfZ2VudXNfSUQgPC0gcmVsYWJfZ2VudXNfSURbLGMoMzozMSldICsgMC4wMDAwMQoKcmVsYWJfZ2VudXNfSURfbG9nIDwtIGxvZzEwKHJlbGFiX2dlbnVzX0lEX2xvZykKCmdlbnVzX0ZBIDwtIGNiaW5kKHJlbGFiX2dlbnVzX0lELCBGQV9zdG9vbFssIGMoMToxOSldKQpnZW51c19GQSRUaW1lIDwtIGZhY3RvcihnZW51c19GQSRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQpgYGAKCkxvb3AgZ2VzYWV0dGlndGUgRkEgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfc2F0IDwtIGZpbHRlcihnZW51c19GQSwgIWlzLm5hKHNhdCkpCgpjb3JyX3NwZWFybWFuX2dlbnVzX3NhdCA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBnZW51c19jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfZ2VudXNfc2F0LCAhaXMubmEoaSkpCiAgCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJHNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRzYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJHNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19zYXQpKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3NhdFtucm93LCJGQSJdID0gInNhdHVyYXRlZCIKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3NhdFtucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3NhdFtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfc2F0W25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfc2F0W25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3NhdFtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfc2F0W25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfc2F0W25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c19zYXQkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX3NhdCRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX3NhdCRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX3NhdCRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19zYXQkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfc2F0JHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCmNvcnJfc2lnX2dlbnVzX3NhdCA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9nZW51c19zYXQsIHAuYWRqdXN0ZWQgPCAwLjA1IHwgcC5hZGp1c3RlZF9QUkUgPCAwLjA1IHwgcC5hZGp1c3RlZF9QT1NUIDwgMC4wNSkKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fZ2VudXNfc2F0LCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL3RhYmVsbGVuL3NhdC5nZW51cy50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBMb3R0ZW4gdm9uIGdlc2FldHRpZ3RlbiBGQSB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J3NhdCcsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDQwMCwgLTEuMyksY29yLmNvZWYuc2l6ZSA9IDUsIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0wLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEsIHg9c2F0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdTYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYSknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nc2F0JywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J3NhdCcsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1NhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J3NhdCcsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0sIHg9c2F0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdTYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JpZmlkb2JhY3Rlcml1bSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0NvcmlvYmFjdGVyaWlhLm9fX0NvcmlvYmFjdGVyaWFsZXMuZl9fQ29yaW9iYWN0ZXJpYWNlYWUuZ19fQ29sbGluc2VsbGEsIHg9c2F0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdTYXR1cmF0ZWQgQ29uY2VudHJhdGlvbiBbbm1vbC9tZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29sbGluc2VsbGEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19FcnlzaXBlbG90cmljaGkub19fRXJ5c2lwZWxvdHJpY2hhbGVzLmZfX0VyeXNpcGVsb3RyaWNoYWNlYWUuZ19fLCB4PXNhdCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignIENvbmNlbnRyYXRpb24gW21nL21sXScpICsgIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZl9fRXJ5c2lwZWxvdHJpY2hhY2VhZSknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUmlrZW5lbGxhY2VhZS5nX18sIHg9c2F0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdTYXR1cmF0ZWQgZmF0dHkgYWNpZHMgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19SaWtlbmVsbGFjZWFlKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J3NhdCcsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19SaWtlbmVsbGFjZWFlLmdfXycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19SaWtlbmVsbGFjZWFlJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtLCB4PXNhdCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignU2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtICknKSsKICBmYWNldF93cmFwKH5UaW1lKQoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYSwgeD1zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ1NhdHVyYXRlZCBmYXR0IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Ba2tlcm1hbnNpYSApJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J3NhdCcsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDQwMCwgLTAuNSksIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0Fra2VybWFuc2lhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nc2F0JywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoNDAwLCAtMC41KSwgeGxhYj0gJ1NhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQWtrZXJtYW5zaWEnKSsKICAKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdzYXQnLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYScsICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoNTAwLCAtMSksIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0Fra2VybWFuc2lhJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmBgYAppbiBBcmJlaXQgCgpgYGB7cn0KcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL3NhdC5mYWVjYWxpLnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J3NhdCcsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJyxjb2xvciA9ICJncmV5NTkiLGZpbGwgPSAibGlnaHRncmF5IiwgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDAsIC0xLjMpLGNvci5jb2VmLnNpemUgPSA4LCB4bGFiPSAnR2Vzw6R0dGlndGUgRmV0dHPDpHVyZW5rb256ZW50cmF0aW9uZW4gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlcyBWb3Jrb21tZW4gZ19fRmFlY2FsaWJhY3Rlcml1bSBbJV0nKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0wLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2VvbV9wb2ludChjb2xvcj0nYmxhY2snLCBzaXplPTIuNSkrCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKQpkZXYub2ZmKCkKCnBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9zYXQub3NjaWxsby5wZGYiLHdpZHRoPTgsIGhlaWdodD0xMCkKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdzYXQnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJyxjb2xvciA9ICJncmV5NTkiLGZpbGwgPSAibGlnaHRncmF5IiwgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDAsIC0yKSxjb3IuY29lZi5zaXplID0gOCwgeGxhYj0gJ0dlc8OkdHRpZ3RlIEZldHRzw6R1cmVua29uemVudHJhdGlvbmVuIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZXMgVm9ya29tbWVuIGdfX09zY2lsbG9zcGlyYSBbJV0nKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0wLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2VvbV9wb2ludChjb2xvcj0nYmxhY2snLCBzaXplPTIuNSkrCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKQpkZXYub2ZmKCkKCnBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9zYXQuYWtrZXJtYW5zaWEucGRmIix3aWR0aD04LCBoZWlnaHQ9MTApCmdnc2NhdHRlcihnZW51c19GQSwgeD0nc2F0JywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLGNvbG9yID0gImdyZXk1OSIsZmlsbCA9ICJsaWdodGdyYXkiLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoMCwgLTAuNyksY29yLmNvZWYuc2l6ZSA9IDgsIHhsYWI9ICdHZXPDpHR0aWd0ZSBGZXR0c8OkdXJlbmtvbnplbnRyYXRpb25lbiBbbm1vbC9nXScsIHlsYWIgPSdSZWxhdGl2ZXMgVm9ya29tbWVuIGdfX0Fra2VybWFuc2lhIFslXScpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZW9tX3BvaW50KGNvbG9yPSdibGFjaycsIHNpemU9Mi41KSsKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpCmRldi5vZmYoKQpgYGAKCkxvb3AgZWluZmFjaCB1bmdlc2FldHRpZ3RlIEZBIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX21vbm8udW5zYXQgPC0gZmlsdGVyKGdlbnVzX0ZBLCAhaXMubmEobW9uby51bnNhdCkpCgpjb3JyX3NwZWFybWFuX2dlbnVzX21vbm8udW5zYXQgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX21vbm8udW5zYXQsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkbW9uby51bnNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRtb25vLnVuc2F0CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRtb25vLnVuc2F0CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX2dlbnVzX21vbm8udW5zYXQpKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX21vbm8udW5zYXRbbnJvdywiRkEiXSA9ICJtb25vLnVuc2F0dXJhdGVkIgogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfbW9uby51bnNhdFtucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX21vbm8udW5zYXRbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX21vbm8udW5zYXRbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19tb25vLnVuc2F0W25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX21vbm8udW5zYXRbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX21vbm8udW5zYXRbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19tb25vLnVuc2F0W25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c19tb25vLnVuc2F0JHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19tb25vLnVuc2F0JHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfbW9uby51bnNhdCRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX21vbm8udW5zYXQkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfbW9uby51bnNhdCRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19tb25vLnVuc2F0JHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCgpjb3JyX3NpZ19nZW51c19tb25vLnVuc2F0IDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX2dlbnVzX21vbm8udW5zYXQsIHAuYWRqdXN0ZWQgPCAwLjA1IHwgcC5hZGp1c3RlZF9QUkUgPCAwLjA1IHwgcC5hZGp1c3RlZF9QT1NUIDwgMC4wNSkKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fZ2VudXNfbW9uby51bnNhdCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy90YWJlbGxlbi9tb25vLnVuc2F0LmdlbnVzLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmBgYAoKUGxvdHRlbiB2b24gZWluZmFjaCB1bmdlc2FldHRpZ3RlbiBGQSB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEsIHg9bW9uby51bnNhdCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignbW9uby51bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0sIHg9bW9uby51bnNhdCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignbW9uby51bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmlmaWRvYmFjdGVyaXVtKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMsIHg9bW9uby51bnNhdCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignbW9uby51bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmFjdGVyb2lkZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19CZXRhcHJvdGVvYmFjdGVyaWEub19fQnVya2hvbGRlcmlhbGVzLmZfX0FsY2FsaWdlbmFjZWFlLmdfX1N1dHRlcmVsbGEsIHg9bW9uby51bnNhdCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignbW9uby51bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX1ByZXZvdGVsbGFjZWFlLmdfX1ByZXZvdGVsbGEsIHg9bW9uby51bnNhdCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignbW9uby51bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUHJldm90ZWxsYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQ29yaW9iYWN0ZXJpaWEub19fQ29yaW9iYWN0ZXJpYWxlcy5mX19Db3Jpb2JhY3RlcmlhY2VhZS5nX19Db2xsaW5zZWxsYSwgeD1tb25vLnVuc2F0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdtb25vLnVuc2F0dXJhdGVkIENvbmNlbnRyYXRpb24gW25tb2wvbWddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvbGxpbnNlbGxhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fRXJ5c2lwZWxvdHJpY2hpLm9fX0VyeXNpcGVsb3RyaWNoYWxlcy5mX19FcnlzaXBlbG90cmljaGFjZWFlLmdfXywgeD1tb25vLnVuc2F0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCcgQ29uY2VudHJhdGlvbiBbbWcvbWxdJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGZfX0VyeXNpcGVsb3RyaWNoYWNlYWUpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX1Jpa2VuZWxsYWNlYWUuZ19fLCB4PW1vbm8udW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ21vbm8udW5zYXR1cmF0ZWQgZmF0dHkgYWNpZHMgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19SaWtlbmVsbGFjZWFlKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtLCB4PW1vbm8udW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ21vbm8udW5zYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0gKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhLCB4PW1vbm8udW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ21vbm8udW5zYXR1cmF0ZWQgZmF0dCBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQWtrZXJtYW5zaWEgKScpKwogIGZhY2V0X3dyYXAoflRpbWUpCgpgYGAKCkxvb3AgendlaWZhY2ggdW5nZXNhZXR0aWd0ZSBGQSB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9nZW51c19kaS51bnNhdCA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYShkaS51bnNhdCkpCgpjb3JyX3NwZWFybWFuX2dlbnVzX2RpLnVuc2F0IDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19kaS51bnNhdCwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRkaS51bnNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRkaS51bnNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkZGkudW5zYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfZGkudW5zYXQpKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2RpLnVuc2F0W25yb3csIkZBIl0gPSAiZGkudW5zYXR1cmF0ZWQiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19kaS51bnNhdFtucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2RpLnVuc2F0W25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19kaS51bnNhdFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2RpLnVuc2F0W25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2RpLnVuc2F0W25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19kaS51bnNhdFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2RpLnVuc2F0W25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c19kaS51bnNhdCRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfZGkudW5zYXQkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19kaS51bnNhdCRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX2RpLnVuc2F0JHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX2RpLnVuc2F0JHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX2RpLnVuc2F0JHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCmNvcnJfc2lnX2dlbnVzX2RpLnVuc2F0IDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX2dlbnVzX2RpLnVuc2F0LCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX2dlbnVzX2RpLnVuc2F0LCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL3RhYmVsbGVuL2RpLnVuc2F0LmdlbnVzLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmBgYApQTG90dGVuIHZvbiB6d2VpZmFjaCB1bmdlc2FldHRpZ3RlbiBGQXMgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bSwgeD1kaS51bnNhdCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignZGkudW5zYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JpZmlkb2JhY3Rlcml1bSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX0JhY3Rlcm9pZGFjZWFlLmdfX0JhY3Rlcm9pZGVzLCB4PWRpLnVuc2F0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdkaS51bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmFjdGVyb2lkZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19CZXRhcHJvdGVvYmFjdGVyaWEub19fQnVya2hvbGRlcmlhbGVzLmZfX0FsY2FsaWdlbmFjZWFlLmdfX1N1dHRlcmVsbGEsIHg9ZGkudW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ2RpLnVuc2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEsIHg9ZGkudW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ2RpLnVuc2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Eb3JlYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19EaWFsaXN0ZXIsIHg9ZGkudW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ2RpLnVuc2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsaXN0ZXIpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKYGBgCgpMb29wIG1laHIgYWxzIHp3ZWlmYWNoIHVuZ2VzYWV0dGlndGUgRkFzIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX21vcmUuMi51bnNhdCA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYShtb3JlLjIudW5zYXQpKQoKY29ycl9zcGVhcm1hbl9nZW51c19tb3JlLjIudW5zYXQgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX21vcmUuMi51bnNhdCwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRtb3JlLjIudW5zYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkbW9yZS4yLnVuc2F0CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRtb3JlLjIudW5zYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfbW9yZS4yLnVuc2F0KSsxCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19tb3JlLjIudW5zYXRbbnJvdywiRkEiXSA9ICJtb3JlLjIudW5zYXR1cmF0ZWQiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19tb3JlLjIudW5zYXRbbnJvdywgIkdlbnVzIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19tb3JlLjIudW5zYXRbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX21vcmUuMi51bnNhdFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX21vcmUuMi51bnNhdFtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19tb3JlLjIudW5zYXRbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX21vcmUuMi51bnNhdFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX21vcmUuMi51bnNhdFtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fZ2VudXNfbW9yZS4yLnVuc2F0JHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19tb3JlLjIudW5zYXQkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19tb3JlLjIudW5zYXQkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19tb3JlLjIudW5zYXQkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfbW9yZS4yLnVuc2F0JHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX21vcmUuMi51bnNhdCRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCgpjb3JyX3NpZ19nZW51c19tb3JlLjIudW5zYXQgPC0gZmlsdGVyKGNvcnJfc3BlYXJtYW5fZ2VudXNfbW9yZS4yLnVuc2F0LCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX2dlbnVzX21vcmUuMi51bnNhdCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy90YWJlbGxlbi9tb3JlLjIudW5zYXQuZ2VudXMudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgpQbG90dGVuIHZvbiBtZWhyIGFscyB6d2VpZmFjaCB1bmdlc2FldHRpZ3RlbiBGQSB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19QcmV2b3RlbGxhY2VhZS5nX19QcmV2b3RlbGxhLCB4PW1vcmUuMi51bnNhdCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignbW9yZS4yLnVuc2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19BY3Rpbm9iYWN0ZXJpYS5vX19CaWZpZG9iYWN0ZXJpYWxlcy5mX19CaWZpZG9iYWN0ZXJpYWNlYWUuZ19fQmlmaWRvYmFjdGVyaXVtLCB4PW1vcmUuMi51bnNhdCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignbW9yZS4yLnVuc2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CaWZpZG9iYWN0ZXJpdW0pJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19CYWN0ZXJvaWRhY2VhZS5nX19CYWN0ZXJvaWRlcywgeD1tb3JlLjIudW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ21vcmUuMi51bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmFjdGVyb2lkZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19CZXRhcHJvdGVvYmFjdGVyaWEub19fQnVya2hvbGRlcmlhbGVzLmZfX0FsY2FsaWdlbmFjZWFlLmdfX1N1dHRlcmVsbGEsIHg9bW9yZS4yLnVuc2F0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdtb3JlLjIudW5zYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwpnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0NvcmlvYmFjdGVyaWlhLm9fX0NvcmlvYmFjdGVyaWFsZXMuZl9fQ29yaW9iYWN0ZXJpYWNlYWUuZ19fQ29sbGluc2VsbGEsIHg9bW9yZS4yLnVuc2F0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdtb3JlLjIudW5zYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvbGxpbnNlbGxhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fVmVpbGxvbmVsbGFjZWFlLmdfX0RpYWxpc3RlciwgeD1tb3JlLjIudW5zYXQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ21vcmUuMi51bnNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbGlzdGVyKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKYGBgCgoKTG9vcCBGQSB3ZW5pZ2VyIGFscyAxNEMgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfbGVzcy4xNCA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYShsZXNzLjE0KSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfbGVzcy4xNCA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBnZW51c19jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfZ2VudXNfbGVzcy4xNCwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRsZXNzLjE0CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJGxlc3MuMTQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJGxlc3MuMTQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfbGVzcy4xNCkrMQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfbGVzcy4xNFtucm93LCJGQSJdID0gImxlc3MuMTQiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19sZXNzLjE0W25yb3csICJHZW51cyJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfbGVzcy4xNFtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfbGVzcy4xNFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2xlc3MuMTRbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfbGVzcy4xNFtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfbGVzcy4xNFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2xlc3MuMTRbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX2dlbnVzX2xlc3MuMTQkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX2xlc3MuMTQkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19sZXNzLjE0JHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfbGVzcy4xNCRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19sZXNzLjE0JHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX2xlc3MuMTQkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfZ2VudXNfbGVzcy4xNCA8LSBmaWx0ZXIoY29ycl9zcGVhcm1hbl9nZW51c19sZXNzLjE0LCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX2dlbnVzX2xlc3MuMTQsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvdGFiZWxsZW4vbGVzcy4xNC5nZW51cy50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gd2VuaWdlciBhbHMgMTRDIEZBIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bSwgeD1sZXNzLjE0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdsZXNzLjE0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CaWZpZG9iYWN0ZXJpdW0pJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19CYWN0ZXJvaWRhY2VhZS5nX19CYWN0ZXJvaWRlcywgeD1sZXNzLjE0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCc+IDE0IGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JhY3Rlcm9pZGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhLCB4PWxlc3MuMTQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ2xlc3MuMTR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0NvcmlvYmFjdGVyaWlhLm9fX0NvcmlvYmFjdGVyaWFsZXMuZl9fQ29yaW9iYWN0ZXJpYWNlYWUuZ19fQ29sbGluc2VsbGEsIHg9bGVzcy4xNCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignPiAxNCBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db2xsaW5zZWxsYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19FcnlzaXBlbG90cmljaGkub19fRXJ5c2lwZWxvdHJpY2hhbGVzLmZfX0VyeXNpcGVsb3RyaWNoYWNlYWUuZ19fLkV1YmFjdGVyaXVtLiwgeD1sZXNzLjE0KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCc+IDE0IGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0V1YmFjdGVyaXVtKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQogIApnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19QcmV2b3RlbGxhY2VhZS5nX19QcmV2b3RlbGxhLCB4PWxlc3MuMTQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJz4gMTQgYy1hdG9tcyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUHJldm90ZWxsYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0sIHg9bGVzcy4xNCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignPiAxNCBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0VyeXNpcGVsb3RyaWNoaS5vX19FcnlzaXBlbG90cmljaGFsZXMuZl9fRXJ5c2lwZWxvdHJpY2hhY2VhZS5nX18uRXViYWN0ZXJpdW0uLCB4PWxlc3MuMTQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJz4gMTQgYy1hdG9tcyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRXViYWN0ZXJpdW0pJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKYGBgCgpMb29wIEMxNC0xNyBGQSB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9nZW51c19jMTQuMTcgPC0gZmlsdGVyKGdlbnVzX0ZBLCAhaXMubmEoYzE0LjE3KSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfYzE0LjE3IDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19jMTQuMTcsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkYzE0LjE3CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJGMxNC4xNwogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkYzE0LjE3CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX2dlbnVzX2MxNC4xNykrMQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfYzE0LjE3W25yb3csIkZBIl0gPSAiYzE0LjE3IgogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfYzE0LjE3W25yb3csICJHZW51cyJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfYzE0LjE3W25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19jMTQuMTdbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19jMTQuMTdbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfYzE0LjE3W25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19jMTQuMTdbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19jMTQuMTdbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX2dlbnVzX2MxNC4xNyRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfYzE0LjE3JHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfYzE0LjE3JHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfYzE0LjE3JHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX2MxNC4xNyRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19jMTQuMTckcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfZ2VudXNfYzE0LjE3IDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX2dlbnVzX2MxNC4xNywgcC5hZGp1c3RlZCA8IDAuMDUgfCBwLmFkanVzdGVkX1BSRSA8IDAuMDUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjA1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9nZW51c19jMTQuMTcsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvdGFiZWxsZW4vYzE0LjE3LmdlbnVzLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmBgYAoKUGxvdHRlbiB2b24gQzE0LTE3IEZBIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSwgeD1jMTQuMTcpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ2MgMTQtMTcgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSArCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0sIHg9YzE0LjE3KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdjIDE0LTE3IGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CaWZpZG9iYWN0ZXJpdW0pJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19CYWN0ZXJvaWRhY2VhZS5nX19CYWN0ZXJvaWRlcywgeD1jMTQuMTcpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJz4gMTQgYy1hdG9tcyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmFjdGVyb2lkZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19CZXRhcHJvdGVvYmFjdGVyaWEub19fQnVya2hvbGRlcmlhbGVzLmZfX0FsY2FsaWdlbmFjZWFlLmdfX1N1dHRlcmVsbGEsIHg9YzE0LjE3KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdjMTQuMTd1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0NvcmlvYmFjdGVyaWlhLm9fX0NvcmlvYmFjdGVyaWFsZXMuZl9fQ29yaW9iYWN0ZXJpYWNlYWUuZ19fQ29sbGluc2VsbGEsIHg9YzE0LjE3KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCcgMTQtMTcgYy1hdG9tcyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29sbGluc2VsbGEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhLCB4PWMxNC4xNykpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignMTQtMTcgYy1hdG9tcyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQWtrZXJtYW5zaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtLCB4PWMxNC4xNykpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignYyAxNC0xNyBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUmlrZW5lbGxhY2VhZS5nX18sIHg9YzE0LjE3KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCcxNC0xNyBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19SaWtlbmVsbGFjZWFlKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2VudXNfRkEka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfXy5CYXJuZXNpZWxsYWNlYWUuLmdfXwpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX18uQmFybmVzaWVsbGFjZWFlLi5nX18sIHg9YzE0LjE3KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCcxNC0xNyBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19CYXJuZXNpZWxsYWNlYWUpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdjMTQuMTcnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdjIDE0LTE3IGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdjMTQuMTcnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJywgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnYyAxNC0xNyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpgYGAKCkxvb3AgQzE4IEZBIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX2MxOCA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYShjMTgpKQoKY29ycl9zcGVhcm1hbl9nZW51c19jMTggPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX2MxOCwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRjMTgKICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkYzE4CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRjMTgKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfYzE4KSsxCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19jMThbbnJvdywiRkEiXSA9ICJjMTgiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19jMThbbnJvdywgIkdlbnVzIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19jMThbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2MxOFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2MxOFtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19jMThbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2MxOFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2MxOFtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fZ2VudXNfYzE4JHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19jMTgkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19jMTgkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19jMTgkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfYzE4JHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX2MxOCRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCgpjb3JyX3NpZ19nZW51c19jMTggPC0gZmlsdGVyKGNvcnJfc3BlYXJtYW5fZ2VudXNfYzE4LCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX2dlbnVzX2MxOCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy90YWJlbGxlbi9jMTguZ2VudXMudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKCmBgYAoKUGxvdHRlbiBDMTggRkEgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhLCB4PWMxOC4xOSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignYyAxOCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bSwgeD1jMTguMTkpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ2MgMTggZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JpZmlkb2JhY3Rlcml1bSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX0JhY3Rlcm9pZGFjZWFlLmdfX0JhY3Rlcm9pZGVzLCB4PWMxOC4xOSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignMTggYy1hdG9tcyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmFjdGVyb2lkZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19CZXRhcHJvdGVvYmFjdGVyaWEub19fQnVya2hvbGRlcmlhbGVzLmZfX0FsY2FsaWdlbmFjZWFlLmdfX1N1dHRlcmVsbGEsIHg9YzE4LjE5KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCcxOCBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMiksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fLCB4PWMxOC4xOSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignMTggYy1hdG9tcyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZl9fUnVtaW5vY29jY2FjZWFlKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEsIHg9YzE4LjE5KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCcxOCBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Ba2tlcm1hbnNpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0sIHg9YzE4LjE5KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdjIDE4IGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0pJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUmlrZW5lbGxhY2VhZS5nX18sIHg9YzE4LjE5KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCcxOCBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19SaWtlbmVsbGFjZWFlKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfXy5CYXJuZXNpZWxsYWNlYWUuLmdfXywgeD1jMTguMTkpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJzE4IGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGZfX0Jhcm5lc2llbGxhY2VhZSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpgYGAKCkxvb3AgQzIwLTI0IEZBIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX2MyMC4yNCA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYShjMjAuMjQpKQoKY29ycl9zcGVhcm1hbl9nZW51c19jMjAuMjQgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX2MyMC4yNCwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRjMjAuMjQKICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkYzIwLjI0CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRjMjAuMjQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfYzIwLjI0KSsxCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19jMjAuMjRbbnJvdywiRkEiXSA9ICJjMjAuMjQiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19jMjAuMjRbbnJvdywgIkdlbnVzIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19jMjAuMjRbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2MyMC4yNFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2MyMC4yNFtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19jMjAuMjRbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2MyMC4yNFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX2MyMC4yNFtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fZ2VudXNfYzIwLjI0JHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19jMjAuMjQkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19jMjAuMjQkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19jMjAuMjQkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfYzIwLjI0JHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX2MyMC4yNCRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCgpjb3JyX3NpZ19nZW51c19jMjAuMjQgPC0gZmlsdGVyKGNvcnJfc3BlYXJtYW5fZ2VudXNfYzIwLjI0LCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX2dlbnVzX2MyMC4yNCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy90YWJlbGxlbi9jMjAuMjQuZ2VudXMudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgpQbG90dGVuIHZvbiBDMjAtMjQgRkEgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhLCB4PWMyMC4yMSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignYyAyMC0yNCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nYzIwLjIxJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnYyAyMC0yNCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0sIHg9YzIwLjIxKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdjIDIwLTI0IGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CaWZpZG9iYWN0ZXJpdW0pJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19CYWN0ZXJvaWRhY2VhZS5nX19CYWN0ZXJvaWRlcywgeD1jMjAuMjEpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJzIwLTI0IGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JhY3Rlcm9pZGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhLCB4PWMyMC4yMSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignMjAtMjQgYy1hdG9tcyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfXywgeD1jMjAuMjEpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJzIwLTI0IGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGZfX1J1bWlub2NvY2NhY2VhZSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEsIHg9YzIwLjIxKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCcyMC0yNCBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Ba2tlcm1hbnNpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0sIHg9YzIwLjIxKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdjIDIwLTI0IGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0pJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J2MyMC4yMScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdjIDIwLTI0IGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19SaWtlbmVsbGFjZWFlLmdfXywgeD1jMjAuMjEpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJzIwLTI0IGMtYXRvbXMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGZfX1Jpa2VuZWxsYWNlYWUpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX18uQmFybmVzaWVsbGFjZWFlLi5nX18sIHg9YzIwLjIxKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJywgJ3N0ZWVsYmx1ZTInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCcyMC0yNCBjLWF0b21zIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19CYXJuZXNpZWxsYWNlYWUpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKYGBgCgpMb29wIHRvdGFsIEZBIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX3RvdGFsIDwtIGZpbHRlcihnZW51c19GQSwgIWlzLm5hKHRvdGFsKSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfdG90YWwgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX3RvdGFsLCAhaXMubmEoaSkpCiAgCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJHRvdGFsCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJHRvdGFsCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSR0b3RhbAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c190b3RhbCkrMQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfdG90YWxbbnJvdywiRkEiXSA9ICJ0b3RhbCIKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3RvdGFsW25yb3csICJHZW51cyJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfdG90YWxbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3RvdGFsW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfdG90YWxbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfdG90YWxbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3RvdGFsW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfdG90YWxbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX2dlbnVzX3RvdGFsJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c190b3RhbCRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX3RvdGFsJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfdG90YWwkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfdG90YWwkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfdG90YWwkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfZ2VudXNfdG90YWwgPC0gZmlsdGVyKGNvcnJfc3BlYXJtYW5fZ2VudXNfdG90YWwsIHAuYWRqdXN0ZWQgPCAwLjA1IHwgcC5hZGp1c3RlZF9QUkUgPCAwLjA1IHwgcC5hZGp1c3RlZF9QT1NUIDwgMC4wNSkKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fZ2VudXNfdG90YWwsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvdGFiZWxsZW4vdG90YWwuZ2VudXMudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgpQbG90dGVuIHZvbiB0b3RhbCBGQSB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEsIHg9dG90YWwpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ3RvdGFsIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMiksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bSwgeD10b3RhbCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYigndG90YWwgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JpZmlkb2JhY3Rlcml1bSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0ndG90YWwnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19BY3Rpbm9iYWN0ZXJpYS5vX19CaWZpZG9iYWN0ZXJpYWxlcy5mX19CaWZpZG9iYWN0ZXJpYWNlYWUuZ19fQmlmaWRvYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdUb3RhbCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmlmaWRvYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMsIHg9dG90YWwpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ3RvdGFsIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CYWN0ZXJvaWRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLmNfX0JldGFwcm90ZW9iYWN0ZXJpYS5vX19CdXJraG9sZGVyaWFsZXMuZl9fQWxjYWxpZ2VuYWNlYWUuZ19fU3V0dGVyZWxsYSwgeD10b3RhbCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYigndG90YWwgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J3RvdGFsJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdUb3RhbCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCmdncGxvdChnZW51c19GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfXywgeD10b3RhbCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYigndG90YWwgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGZfX1J1bWlub2NvY2NhY2VhZSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYSwgeD10b3RhbCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYigndG90YWwgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0Fra2VybWFuc2lhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bSwgeD10b3RhbCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYigndG90YWwgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0pJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUmlrZW5lbGxhY2VhZS5nX18sIHg9dG90YWwpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ3RvdGFsIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19SaWtlbmVsbGFjZWFlKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSd0b3RhbCcsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19SaWtlbmVsbGFjZWFlLmdfXycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnVG90YWwgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGZfX1Jpa2VuZWxsYWNlYWUnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX18uQmFybmVzaWVsbGFjZWFlLi5nX18sIHg9dG90YWwpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInLCAnc3RlZWxibHVlMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ3RvdGFsIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19CYXJuZXNpZWxsYWNlYWUpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3QoZ2VudXNfRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX18uUnVtaW5vY29jY3VzLiwgeD10b3RhbCkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYigndG90YWwgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfXy5SdW1pbm9jb2NjdXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpgYGAKCkxvb3AgT21lZ2EzIEZBIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9Cgpjb3JyX21hcF9nZW51c19PbWVnYTMgPC0gZmlsdGVyKGdlbnVzX0ZBLCAhaXMubmEoT21lZ2EzKSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2EzIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19PbWVnYTMsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkT21lZ2EzCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJE9tZWdhMwogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkT21lZ2EzCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX2dlbnVzX09tZWdhMykrMQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2EzW25yb3csIkZBIl0gPSAiT21lZ2EzIgogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2EzW25yb3csICJHZW51cyJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2EzW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19PbWVnYTNbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19PbWVnYTNbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2EzW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19PbWVnYTNbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19PbWVnYTNbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX2dlbnVzX09tZWdhMyRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2EzJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2EzJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2EzJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX09tZWdhMyRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19PbWVnYTMkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfZ2VudXNfT21lZ2EzIDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX2dlbnVzX09tZWdhMywgcC5hZGp1c3RlZCA8IDAuMDUgfCBwLmFkanVzdGVkX1BSRSA8IDAuMDUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjA1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9nZW51c19PbWVnYTMsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvdGFiZWxsZW4vT21lZ2EzLmdlbnVzLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCgpgYGAKClBsb3R0ZW4gdm9uIE9tZWdhMyBGQSB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdPbWVnYTMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtubW9sL2ddJywgY29yLmNvZWYuY29vcmQgPWMoMCwgLTEuOSksIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nT21lZ2EzJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbbm1vbC9nXScsIGNvci5jb2VmLmNvb3JkID1jKDAsIC0xLjkpLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCnRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J09tZWdhMycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJyxsYWJlbCA9ICdQcm9iYW5kJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0VyeXNpcGVsb3RyaWNoaS5vX19FcnlzaXBlbG90cmljaGFsZXMuZl9fRXJ5c2lwZWxvdHJpY2hhY2VhZS5nX18uRXViYWN0ZXJpdW0uLCB4PU9tZWdhMykpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRXViYWN0ZXJpdW0pJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J09tZWdhMycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fRXJ5c2lwZWxvdHJpY2hpLm9fX0VyeXNpcGVsb3RyaWNoYWxlcy5mX19FcnlzaXBlbG90cmljaGFjZWFlLmdfXy5FdWJhY3Rlcml1bS4nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0V1YmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J09tZWdhMycsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0NvcmlvYmFjdGVyaWlhLm9fX0NvcmlvYmFjdGVyaWFsZXMuZl9fQ29yaW9iYWN0ZXJpYWNlYWUuZ19fQ29sbGluc2VsbGEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvbGxpbnNlbGxhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J09tZWdhMycsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0NvcmlvYmFjdGVyaWlhLm9fX0NvcmlvYmFjdGVyaWFsZXMuZl9fQ29yaW9iYWN0ZXJpYWNlYWUuZ19fJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19Db3Jpb2JhY3RlcmlhY2VhZScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdPbWVnYTMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0JhY2lsbGkub19fTGFjdG9iYWNpbGxhbGVzLmZfX1N0cmVwdG9jb2NjYWNlYWUuZ19fU3RyZXB0b2NvY2N1cycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3RyZXB0b2NvY2N1cycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdPbWVnYTMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQ29wcm9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J09tZWdhMycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX18uUnVtaW5vY29jY3VzLicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUnVtaW5vY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J09tZWdhMycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKYGBgCgpMb29wIE9tZWdhNiBGQSB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9nZW51c19PbWVnYTYgPC0gZmlsdGVyKGdlbnVzX0ZBLCAhaXMubmEoT21lZ2E2KSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2E2IDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19PbWVnYTYsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkT21lZ2E2CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJE9tZWdhNgogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkT21lZ2E2CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX2dlbnVzX09tZWdhNikrMQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2E2W25yb3csIkZBIl0gPSAiT21lZ2E2IgogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2E2W25yb3csICJHZW51cyJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2E2W25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19PbWVnYTZbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19PbWVnYTZbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2E2W25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19PbWVnYTZbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19PbWVnYTZbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX2dlbnVzX09tZWdhNiRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2E2JHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2E2JHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfT21lZ2E2JHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX09tZWdhNiRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19PbWVnYTYkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfZ2VudXNfT21lZ2E2IDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX2dlbnVzX09tZWdhNiwgcC5hZGp1c3RlZCA8IDAuMDUgfCBwLmFkanVzdGVkX1BSRSA8IDAuMDUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjA1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9nZW51c19PbWVnYTYsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmEgZmVjZXMvdGFiZWxsZW4vT21lZ2E2LmdlbnVzLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmBgYAoKUExvdHRlbiB2b24gT21lZ2E2IEZBIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J09tZWdhNicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J09tZWdhNicsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIGV4Y3JldGlvbiByYXRlIFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J09tZWdhNicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fRXJ5c2lwZWxvdHJpY2hpLm9fX0VyeXNpcGVsb3RyaWNoYWxlcy5mX19FcnlzaXBlbG90cmljaGFjZWFlLmdfXy5FdWJhY3Rlcml1bS4nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRXViYWN0ZXJpdW0nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nT21lZ2E2JywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQ29yaW9iYWN0ZXJpaWEub19fQ29yaW9iYWN0ZXJpYWxlcy5mX19Db3Jpb2JhY3RlcmlhY2VhZS5nX19Db2xsaW5zZWxsYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db2xsaW5zZWxsYScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdPbWVnYTYnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19Db3Jpb2JhY3RlcmlpYS5vX19Db3Jpb2JhY3RlcmlhbGVzLmZfX0NvcmlvYmFjdGVyaWFjZWFlLmdfXycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZl9fQ29yaW9iYWN0ZXJpYWNlYWUnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nT21lZ2E2JywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19CYWNpbGxpLm9fX0xhY3RvYmFjaWxsYWxlcy5mX19TdHJlcHRvY29jY2FjZWFlLmdfX1N0cmVwdG9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3RyZXB0b2NvY2N1cycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdPbWVnYTYnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQ29wcm9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29wcm9jb2NjdXMnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nT21lZ2E2JywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRmFlY2FsaWJhY3Rlcml1bScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdPbWVnYTYnLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Ba2tlcm1hbnNpYScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdPbWVnYTYnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fLlJ1bWlub2NvY2N1cy4nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUnVtaW5vY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpgYGAKCkxvb3Agb21lZ2E2L29tZWdhMy1yYXRpbyB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9nZW51c19yYXRpbyA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYShyYXRpbykpCgpjb3JyX3NwZWFybWFuX2dlbnVzX3JhdGlvIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19yYXRpbywgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRyYXRpbwogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRyYXRpbwogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkcmF0aW8KICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfcmF0aW8pKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3JhdGlvW25yb3csIkZBIl0gPSAicmF0aW8iCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19yYXRpb1tucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3JhdGlvW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19yYXRpb1tucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3JhdGlvW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3JhdGlvW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19yYXRpb1tucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3JhdGlvW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c19yYXRpbyRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfcmF0aW8kcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19yYXRpbyRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX3JhdGlvJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX3JhdGlvJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX3JhdGlvJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCmNvcnJfc2lnX2dlbnVzX3JhdGlvIDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX2dlbnVzX3JhdGlvLCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX2dlbnVzX3JhdGlvLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL3RhYmVsbGVuL3JhdGlvLmdlbnVzLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmBgYAoKUExvdHRlbiB2b24gb21lZ2E2L29tZWdhMy1yYXRpbyB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdyYXRpbycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ29tZWdhIDYvb21lZ2EgMyByYXRpbyBmZWNhbCcsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J3JhdGlvJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0xhY2hub3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdvbWVnYSA2L29tZWdhIDMgcmF0aW8gZmVjYWwnLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fTGFjaG5vc3BpcmEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0ncmF0aW8nLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ29tZWdhIDYvb21lZ2EgMyByYXRpbyBmZWNhbCcsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CYWN0ZXJvaWRlcycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0ncmF0aW8nLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19Db3Jpb2JhY3RlcmlpYS5vX19Db3Jpb2JhY3RlcmlhbGVzLmZfX0NvcmlvYmFjdGVyaWFjZWFlLmdfX0NvbGxpbnNlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdvbWVnYSA2L29tZWdhIDMgcmF0aW8gZmVjYWwnLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29sbGluc2VsbGEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0ncmF0aW8nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fLlJ1bWlub2NvY2N1cy4nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ29tZWdhIDYvb21lZ2EgMyByYXRpbyBmZWNhbCcsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19SdW1pbm9jb2NjdXMnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0ncmF0aW8nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19WZWlsbG9uZWxsYWNlYWUuZ19fUGhhc2NvbGFyY3RvYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdvbWVnYSA2L29tZWdhIDMgcmF0aW8gZmVjYWwnLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUGhhc2NvbGFyY3RvYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0ncmF0aW8nLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19BY3Rpbm9iYWN0ZXJpYS5vX19CaWZpZG9iYWN0ZXJpYWxlcy5mX19CaWZpZG9iYWN0ZXJpYWNlYWUuZ19fQmlmaWRvYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdvbWVnYSA2L29tZWdhIDMgcmF0aW8gZmVjYWwnLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmlmaWRvYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmBgYAoKTG9vcCB1bmdlc2FldHRpZ3RlIEZBIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9Cgpjb3JyX21hcF9nZW51c191bnNhdCA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYSh1bnNhdCkpCgpjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0IDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c191bnNhdCwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCR1bnNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSR1bnNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkdW5zYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfdW5zYXQpKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0W25yb3csIkZBIl0gPSAidW5zYXQiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c191bnNhdFtucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0W25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c191bnNhdFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0W25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0W25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c191bnNhdFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0W25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c191bnNhdCRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfdW5zYXQkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c191bnNhdCRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0JHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0JHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0JHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCmNvcnJfc2lnX2dlbnVzX3Vuc2F0IDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0LCBwLmFkanVzdGVkIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUFJFIDwgMC4wNSB8IHAuYWRqdXN0ZWRfUE9TVCA8IDAuMDUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0LCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL3RhYmVsbGVuL3Vuc2F0LmdlbnVzLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmBgYAoKCjIuNSBPbWVnYS1GYSBBbmFseXNlbiwgQXVmbmFoZW0gdWViZXIgTmFocnVuZywgQXVzc2NoZWlkdW5nLCBBdXNzY2hlaWR1bmdzcmF0ZSAsIEFic29ycHRpb25zcmF0ZSwgRVBBLCBESEEKCkxhZGVuIGRlciBNZXRhZGF0ZW4gdW5kIHRlc3RlbiBhdWYgTm9ybWFsdmVydGVpbHVuZwoKYGBge3J9CkZBX3N0b29sLm8gPC0gcmVhZC50YWJsZSgiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvT21lZ2EgYXVmbmFobWUgMS50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLGhlYWQ9VCkKVmlldyhGQV9zdG9vbCkKCgpGQV9zdG9vbC5vIDwtIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wubywgIVByb2JhbmQgPT0gIjMzTVAiKSkKCgpGQV9jb2xuYW1lcy5vIDwtIGNvbG5hbWVzKEZBX3N0b29sLm9bLCBjKDIxOjIzKV0pCgpuZC5GQS5vIDwtIGRhdGEuZnJhbWUoKQoKZm9yIChpIGluIEZBX2NvbG5hbWVzLm8pICB7CiAgZml0IDwtIHNoYXBpcm8udGVzdChhcy5tYXRyaXgoYXMuZGF0YS5mcmFtZShsYXBwbHkoRkFfc3Rvb2wub1ssaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXMubnVtZXJpYykpKSkKICBwID0gZml0JHAudmFsdWUKICBucm93ID0gbnJvdyhuZC5GQS5vKSsxCiAgbmQuRkEub1tucm93LCAiY29sdW1uIl0gPSBpCiAgbmQuRkEub1tucm93LCAicC52YWx1ZSJdID0gcm91bmQocCwgNCkKICAKfQoKYGBgCgpQbG90dGVuIGRlciBOb3JtYWx2ZXJ0ZWlsdW5nZW4KCmBgYHtyfQpnZ3FxcGxvdChGQV9zdG9vbC5vJExpbm9sZW5zYWV1cmVfZiwgeWxhYiA9ICJGZWNhbCBvbWVnYSAzIEZBIGNvbmNlbnRyYXRpb24gW2ddIiwgeGxhYiA9ICJTYW1wbGVJRCIpCmdncXFwbG90KEZBX3N0b29sLm8kTGlub2xzYWV1cmVfZiwgeWxhYiA9ICJGZWNhbCBvbWVnYSA2IEZBIGNvbmNlbnRyYXRpb24gW2ddIiwgeGxhYiA9ICJTYW1wbGVJRCIpCmdncXFwbG90KEZBX3N0b29sLm8kTGlub2xlbnNhZXVyZV9pLCB5bGFiID0gIkludGFrZSBvbWVnYSAzIEZBIGNvbmNlbnRyYXRpb24gW2ddIiwgeGxhYiA9ICJTYW1wbGVJRCIpCgpnZ3FxcGxvdChGQV9zdG9vbC5vJEVQQV9pLCB5bGFiID0gIkludGFrZSBFUEEgIFtnXSIsIHhsYWIgPSAiU2FtcGxlSUQiKQpnZ3FxcGxvdChGQV9zdG9vbC5vJERIQV9pLCB5bGFiID0gIkludGFrZSBESEEgIFtnXSIsIHhsYWIgPSAiU2FtcGxlSUQiKQoKZ2dxcXBsb3QoRkFfc3Rvb2wubyRBUl9MaW5vbGVuc2FldXJlLCB5bGFiID0gInByZWNpcGl0YXRpb24gcmF0ZSBvbWVnYSAzIEZBIGNvbmNlbnRyYXRpb24gWyVdIiwgeGxhYiA9ICJTYW1wbGVJRCIpCmdncXFwbG90KEZBX3N0b29sLm8kQVJfTGlub2xzYWV1cmUsIHlsYWIgPSAicHJlY2lwaXRhdGlvbiByYXRlIG9tZWdhIDYgRkEgY29uY2VudHJhdGlvbiBbJV0iLCB4bGFiID0gIlNhbXBsZUlEIikKCmdncXFwbG90KEZBX3N0b29sLm8kQV9MaW5vbGVuc2FldXJlLCB5bGFiID0gIkludGFrZSBpbiB0aGUgYm9keSBvbWVnYSAzIEZBICBbZ10iLCB4bGFiID0gIlNhbXBsZUlEIikKZ2dxcXBsb3QoRkFfc3Rvb2wubyRBX0xpbm9sc2FldXJlLCB5bGFiID0gIkludGFrZSBpbiB0aGUgYm9keSBvbWVnYSA2IEZBIFtnXSIsIHhsYWIgPSAiU2FtcGxlSUQiKQoKZ2dxcXBsb3QoRkFfc3Rvb2wubyRBUF9MaW5vbGVuc2FldXJlLCB5bGFiID0gInBlcmNlbnRhZ2UgaW50YWtlIGluIHRoZSBib2R5IG9tZWdhIDMgRkEgIFtnXSIsIHhsYWIgPSAiU2FtcGxlSUQiKQpnZ3FxcGxvdChGQV9zdG9vbC5vJEFQX0xpbm9sc2FldXJlLCB5bGFiID0gInBlcmNlbnRhZ2UgaW50YWtlIGluIHRoZSBib2R5IG9tZWdhIDYgRkEgW2ddIiwgeGxhYiA9ICJTYW1wbGVJRCIpCgoKYGBgCgpGaWx0ZXJuIG5hY2ggUFJFIHVuZCBQT1NUCgpgYGB7cn0KCkZBX3N0b29sX3BhaXJzLm8gPC0gZmlsdGVyKEZBX3N0b29sLm8sIFByb2JhbmQgPT0gIjA1QVAiIHwgUHJvYmFuZCA9PSAiMDZXVCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMDdSVyIgfCBQcm9iYW5kID09ICIxM0JTIiB8IFByb2JhbmQgPT0gIjE3U0siCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjIyV1MiIHwgUHJvYmFuZCA9PSAiMjVGRSIgfCBQcm9iYW5kID09ICIyNkZCIgogICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIyOEhNIiB8IFByb2JhbmQgPT0gIjI5TUsiIHwgUHJvYmFuZCA9PSAiMzBIQiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzFLRSIgfCBQcm9iYW5kID09ICIzMkZHIiB8IFByb2JhbmQgPT0gIjM1QUQifCBQcm9iYW5kID09ICIzNkVSIgogICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzN1NEIiB8IFByb2JhbmQgPT0gIjM4QVIiIHwgUHJvYmFuZCA9PSAiNDBXQSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNDFNTCIgfCBQcm9iYW5kID09ICI0NUdMIiB8IFByb2JhbmQgPT0gIjQ3T1QiCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjUwRE0iIHwgUHJvYmFuZCA9PSAiNTNCRCIgfCBQcm9iYW5kID09ICI1NFNMIgogICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI1N01UIiB8IFByb2JhbmQgPT0gIjY5SEwiIHwgUHJvYmFuZCA9PSAiNzRTQSIpCkZBX3N0b29sX3BhaXJzLm8kUHJvYmFuZAoKCgpGQV9zdG9vbF9wYWlyc19QUC5vIDwtIGZpbHRlcihGQV9zdG9vbF9wYWlycy5vLCBUaW1lPT0iUFJFIiB8IFRpbWU9PSJQT1NUIikKCmBgYAoKTG9vcCBmdWVyIFdpbGNveG9uLXRlc3Qgendpc2NoZW4gUFJFIHVuZCBQT1NUCgpgYGB7cn0Kd2lsY294X0ZBLm88LSBkYXRhX2ZyYW1lKCkKCgpmb3IgKGkgaW4gRkFfY29sbmFtZXMubykgewogIAogIHRtcCA8LSBGQV9zdG9vbF9wYWlyc19QUC5vICU+JSBkcm9wX25hKGkpIAogIAogIHggPC0gYXMubWF0cml4KGFzLmRhdGEuZnJhbWUobGFwcGx5KHRtcFssaV0sIGFzLm51bWVyaWMpKSkKICAKICB5IDwtIEZBX3N0b29sX3BhaXJzX1BQLm8kVGltZSAKICAKICB0bXBfd2lsY294IDwtIHBhaXJ3aXNlLndpbGNveC50ZXN0KHgsIHksIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IFQpCiAgCiAgcCA8LSB0bXBfd2lsY294JHAudmFsdWUKICAKICBucm93ID0gbnJvdyh3aWxjb3hfRkEubykrMQogIAogIHdpbGNveF9GQS5vW25yb3csICJGQSJdIDwtIGkgCiAgCiAgCiAgCiAgd2lsY294X0ZBLm9bbnJvdywgIk1lYW4gUFJFIl0gPC1yb3VuZChtZWFuKHN1YnNldChmaWx0ZXIoRkFfc3Rvb2xfcGFpcnMubyxUaW1lID09ICJQUkUiKVssaV0sIWlzLm5hKGkpLG5hLnJtID0gVFJVRSksIDIsIG1lYW4sICBuYS5ybSA9IFRSVUUpLCA0KQogIAogIHdpbGNveF9GQS5vW25yb3csICJzZCBQUkUiXSA8LXJvdW5kKHNkKGMoc3Vic2V0KGZpbHRlcihGQV9zdG9vbF9wYWlycy5vLFRpbWUgPT0gIlBSRSIpWyxpXSwhaXMubmEoaSksbmEucm0gPSBUUlVFKSwgbmEucm0gPSBUUlVFKSksIDQpCiAgCiAgd2lsY294X0ZBLm9bbnJvdywgIk1lYW4gUE9TVCJdIDwtcm91bmQobWVhbihzdWJzZXQoZmlsdGVyKEZBX3N0b29sX3BhaXJzLm8sVGltZSA9PSAiUE9TVCIpWyxpXSwhaXMubmEoaSksIG5hLnJtID0gVFJVRSksIDIsIG1lYW4sICBuYS5ybSA9IFRSVUUpLCA0KQogIAogIHdpbGNveF9GQS5vW25yb3csICJzZCBQT1NUIl0gPC0gcm91bmQoc2QoYyhzdWJzZXQoZmlsdGVyKEZBX3N0b29sX3BhaXJzLm8sVGltZSA9PSAiUE9TVCIpWyxpXSwhaXMubmEoaSksIG5hLnJtID0gVFJVRSksbmEucm0gPSBUUlVFKSksIDQpCiAgCiAgd2lsY294X0ZBLm9bbnJvdywgInAudmFsdWUiXSA8LSByb3VuZChwLCA0KSB9CgoKYGBgCgpCb3hwbG90IGRlciBPbWVnYS1GQSBqZSBaZWl0cHVua3QKYWxsZSBGQQpgYGB7cn0KRkFfc3Rvb2wubWVsdC5vIDwtIG1lbHQoRkFfc3Rvb2xfcGFpcnMubywgaWQudmFycyA9ICdUaW1lJywgbWVhc3VyZS52YXJzID0gYygnTGlub2xlbnNhZXVyZV9mJywgJ0xpbm9sc2FldXJlX2YnLCAnTGlub2xlbnNhZXVyZV9pJywgJ0xpbm9sc2FldXJlX2knKSkKCgpGQV9zdG9vbC5tZWx0Lm8gPC0gcmVuYW1lKEZBX3N0b29sLm1lbHQubywgRkE9dmFyaWFibGUpCkZBX3N0b29sLm1lbHQubyA8LSByZW5hbWUoRkFfc3Rvb2wubWVsdC5vLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKCkZBX3N0b29sLm1lbHQubyRUaW1lIDwtIGZhY3RvcihGQV9zdG9vbC5tZWx0Lm8kVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmdncGxvdChGQV9zdG9vbC5tZWx0Lm8sYWVzKHg9VGltZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSkpICsKICB4bGFiICgnVGltZSBQb2ludCcpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW2ddJykgKyAKICBnZW9tX2JveHBsb3QoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscyA9IGMoIm9tZWdhIDMgZmVjYWwiLCAib21lZ2EgNiBmZWNhbCIsIm9tZWdhIDMgaW50YWtlIiwgIm9tZWdhIDYgaW50YWtlIiksIAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoInRvbWF0byIsICJ5ZWxsb3dncmVlbiIsICJzdGVlbGJsdWUyIiwgImRlZXBwaW5rMiIpKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKSsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKQoKCmBgYApPbWVnYSAzIGluIG1vbAoKYGBge3J9CkZBX3N0b29sLm1lbHQubzEgPC0gbWVsdChGQV9zdG9vbF9wYWlycy5vLCBpZC52YXJzID0gYygnVGltZScsJ1Byb2JhbmQnKSwgbWVhc3VyZS52YXJzID0gYygnTGlub2xlbnNhZXVyZV9tb2wnKSkKCgpGQV9zdG9vbC5tZWx0Lm8xIDwtIHJlbmFtZShGQV9zdG9vbC5tZWx0Lm8xLCBGQT12YXJpYWJsZSkKRkFfc3Rvb2wubWVsdC5vMSA8LSByZW5hbWUoRkFfc3Rvb2wubWVsdC5vMSwgQ29uY2VudHJhdGlvbj12YWx1ZSkKIApGQV9zdG9vbC5tZWx0Lm8xJFRpbWUgPC0gZmFjdG9yKEZBX3N0b29sLm1lbHQubzEkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmdncGxvdChGQV9zdG9vbC5tZWx0Lm8xLGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gRkEpLGxhYmVsPSAnUHJvYmFuZCcpICsKICB4bGFiICgnVGltZSBQb2ludCcpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvZ10nKSArIAogIGdlb21fYm94cGxvdCgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygib21lZ2EgMyBmZWNhbCIpLCAKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJ0b21hdG8iKSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikrCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFRSVUUsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkrCmdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkKCgpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvTGlub2xzw6R1cmUucHJvYmFuZHMucGRmIix3aWR0aD03LjUsIGhlaWdodD0xMCkKZ2dwYWlyZWQoRkFfc3Rvb2wubWVsdC5vMSwgeD0nVGltZScsIHk9J0NvbmNlbnRyYXRpb24nLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnVGltZScsIHBhbGV0dGUgPSBjKCdza3libHVlJywnb3JjaGlkNCcpLCBsaW5lLmNvbG9yID0gJ2dyZXk2MCcsIGxpbmUuc2l6ZSA9IDAuNCwgZ3JvdXAgPSAnUHJvYmFuZCcsIGZhY2V0LmJ5ID0gJ0ZBJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFKSArCiAgeGxhYignRsOka2FsZSBhbHBoYS1MaW5vbGVuc8OkdXJla29uemVudHJhdGlvbmVuIFtubW9sL2ddJykgKyB5bGFiKCdLb256ZW50cmF0aW9uIFtubW9sL2ddJykrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0wLCBoanVzdD0xKSkKZGV2Lm9mZigpCgpgYGAKCk9tZWdhIDYgaW4gbW9sCgpgYGB7cn0KRkFfc3Rvb2wubWVsdC5vMiA8LSBtZWx0KEZBX3N0b29sX3BhaXJzLm8sIGlkLnZhcnMgPSBjKCdUaW1lJywnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdMaW5vbHNhZXVyZV9tb2wnKSkKCiAKRkFfc3Rvb2wubWVsdC5vMiA8LSByZW5hbWUoRkFfc3Rvb2wubWVsdC5vMiwgRkE9dmFyaWFibGUpCkZBX3N0b29sLm1lbHQubzI8LSByZW5hbWUoRkFfc3Rvb2wubWVsdC5vMiwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCkZBX3N0b29sLm1lbHQubzIkVGltZSA8LSBmYWN0b3IoRkFfc3Rvb2wubWVsdC5vMiRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKZ2dwbG90KEZBX3N0b29sLm1lbHQubzIsYWVzKHg9VGltZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSksbGFiZWw9ICdQcm9iYW5kJykgKwogIHhsYWIgKCdUaW1lIFBvaW50JykgKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9nXScpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJvbWVnYSA2IGZlY2FsIiksIAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoInllbGxvd2dyZWVuIikpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkKCgpnZ3BhaXJlZChGQV9zdG9vbC5tZWx0Lm8yLCB4PSdUaW1lJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgZmFjZXQuYnkgPSAnRkEnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdmZWNhbCBvbWVnYSA2JykgKyB5bGFiKCdDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkKCmBgYAoKT21lZ2EgMyBBdWZuYWhtZSBQUkUgdW5kIFBPU1QKCmBgYHtyfQpGQV9zdG9vbC5tZWx0Lm8zIDwtIG1lbHQoRkFfc3Rvb2xfcGFpcnMubywgaWQudmFycyA9IGMoJ1RpbWUnLCdQcm9iYW5kJyksIG1lYXN1cmUudmFycyA9IGMoJ0xpbm9sZW5zYWV1cmVfaScpKQoKCkZBX3N0b29sLm1lbHQubzMgPC0gcmVuYW1lKEZBX3N0b29sLm1lbHQubzMsIEZBPXZhcmlhYmxlKQpGQV9zdG9vbC5tZWx0Lm8zIDwtIHJlbmFtZShGQV9zdG9vbC5tZWx0Lm8zLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKIApGQV9zdG9vbC5tZWx0Lm8zJFRpbWUgPC0gZmFjdG9yKEZBX3N0b29sLm1lbHQubzMkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmdncGxvdChGQV9zdG9vbC5tZWx0Lm8zLGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gRkEpKSArCiAgeGxhYiAoJ1RpbWUgUG9pbnQnKSArIHlsYWIgKCdDb25jZW50cmF0aW9uIFtnXScpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJvbWVnYSAzIGludGFrZSIsICJvbWVnYSA2IGludGFrZSIpLCAKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkKCgpnZ3BhaXJlZChGQV9zdG9vbC5tZWx0Lm8zLCB4PSdUaW1lJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgZmFjZXQuYnkgPSAnRkEnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdpbnRha2Ugb21lZ2EgMycpICsgeWxhYignQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApCgpgYGAKCk9tZWdhIDYgQXVmbmFobWUgUFJFIHVuZCBQT1NUCgpgYGB7cn0KRkFfc3Rvb2wubWVsdC5vNCA8LSBtZWx0KEZBX3N0b29sX3BhaXJzLm8sIGlkLnZhcnMgPSBjKCdUaW1lJywnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdMaW5vbHNhZXVyZV9pJykpCgogCkZBX3N0b29sLm1lbHQubzQgPC0gcmVuYW1lKEZBX3N0b29sLm1lbHQubzQsIEZBPXZhcmlhYmxlKQpGQV9zdG9vbC5tZWx0Lm80IDwtIHJlbmFtZShGQV9zdG9vbC5tZWx0Lm80LCBDb25jZW50cmF0aW9uPXZhbHVlKQoKCkZBX3N0b29sLm1lbHQubzQkVGltZSA8LSBmYWN0b3IoRkFfc3Rvb2wubWVsdC5vNCRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKZ2dwbG90KEZBX3N0b29sLm1lbHQubzQsYWVzKHg9VGltZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBGQSkpICsKICB4bGFiICgnVGltZSBQb2ludCcpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW2ddJykgKyAKICBnZW9tX2JveHBsb3QoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscyA9IGMoIm9tZWdhIDYgaW50YWtlIiksIAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoImRlZXBwaW5rIikpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkKCgpnZ3BhaXJlZChGQV9zdG9vbC5tZWx0Lm80LCB4PSdUaW1lJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgZmFjZXQuYnkgPSAnRkEnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdpbnRha2Ugb21lZ2EgNicpICsgeWxhYignQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApCmBgYApgYGB7cn0KCmBgYAoKMy4zIEtvcnJlbGF0aW9uc2FuYWx5c2VuIE9tZWdhLUZBIHVuZCBUYXhhCk1ldGFkYXRlbiBob2NobGFkZW4sIGZpbHRlcm4gdW5kIHN5bmNocm9uaXNpZXJlbgoKYGBge3J9CgpyZWxhYl9tZWFucyA8LSByZWFkLnRhYmxlKCcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9yZWxhdGl2ZSBhYnVuZGFuY2UvcmVsYWJfbWVhbnNfcGVyX3RpbWVwb2ludC50eHQnLCBzZXAgPSdcdCcsIGNvbW1lbnQ9JycsIGhlYWQ9VCkKCnJlbGFiX21lYW5zX21lbHQgPC0gbWVsdChyZWxhYl9tZWFucywgaWQ9YygnUHJvYmFuZCcsICdUaW1lJykpCgpyZWxhYl9tZWFuc19tZWx0IDwtIGRwbHlyOjpyZW5hbWUocmVsYWJfbWVhbnNfbWVsdCwgVGF4YT12YXJpYWJsZSkKCnJlbGFiX21lYW5zX21lbHQgPC0gZHBseXI6OnJlbmFtZShyZWxhYl9tZWFuc19tZWx0LCBSZWxhdGl2ZV9BYnVuZGFuY2U9dmFsdWUpCgpyZWxhYl9waHlsdW0gPC0gc3Vic2V0KHJlbGFiX21lYW5zX21lbHQsICFncmVwbCgiZ19ffGZfX3xvX198Y19fIiwgcmVsYWJfbWVhbnNfbWVsdCRUYXhhKSkKCnJlbGFiX3BoeWx1bSA8LSBzdWJzZXQocmVsYWJfcGh5bHVtLCAhZ3JlcGwoImtfX0FyY2hhZWEiLCByZWxhYl9waHlsdW0kVGF4YSkpCgpyZWxhYl9waHlsdW0kVGltZSA8LSBmYWN0b3IocmVsYWJfcGh5bHVtJFRpbWUsIGxldmVscz1jKCdQUkUnLCdQT1NUJywnRk9MTE9XLVVQJykpCgpyZWxhYl9waHlsdW1fc3ByZWFkIDwtIHNwcmVhZChyZWxhYl9waHlsdW0sIFRheGEsIFJlbGF0aXZlX0FidW5kYW5jZSwgc2VwID0gTlVMTCkKCnJlbGFiX2dlbnVzIDwtIHN1YnNldChyZWxhYl9tZWFuc19tZWx0LCBncmVwbCgiZ19fIiwgcmVsYWJfbWVhbnNfbWVsdCRUYXhhKSkKCnJlbGFiX2dlbnVzIDwtIHN1YnNldChyZWxhYl9nZW51cywgIWdyZXBsKCJrX19BcmNoYWVhIiwgcmVsYWJfZ2VudXMkVGF4YSkpCgpyZWxhYl9nZW51cyRUaW1lIDwtIGZhY3RvcihyZWxhYl9nZW51cyRUaW1lLCBsZXZlbHMgPSBjKCdQUkUnLCdQT1NUJywnRk9MTE9XLVVQJykpCgpyZWxhYl9nZW51c19zcHJlYWQgPC0gc3ByZWFkKHJlbGFiX2dlbnVzLCBUYXhhLCBSZWxhdGl2ZV9BYnVuZGFuY2UsIHNlcCA9IE5VTEwpCgoKRkFfc3Rvb2wubyA8LSByZWFkLnRhYmxlKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBmZWNlcy9GQSBmZWNhbC9vbWVnYS9PbWVnYSBhdWZuYWhtZSAudHh0Iiwgc2VwID0gJ1x0JywgY29tbWVudD0nJyxoZWFkPVQpClZpZXcoRkFfc3Rvb2wpCgoKRkFfc3Rvb2wubyA8LSBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLm8sICFQcm9iYW5kID09ICIzM01QIikpCgoKcmVsYWJfcGh5bHVtX0lEIDwtIHJlbGFiX3BoeWx1bV9zcHJlYWQKCnJlbGFiX3BoeWx1bV9JRCA8LSBtdXRhdGUocmVsYWJfcGh5bHVtX0lELCBTYW1wbGVJRCA9IHBhc3RlKFByb2JhbmQsIFRpbWUsc2VwPSIuIikpCgpyb3cubmFtZXMocmVsYWJfcGh5bHVtX0lEKSA8LSByZWxhYl9waHlsdW1fSUQkU2FtcGxlSUQKCnJlbGFiX2dlbnVzX0lEIDwtIHJlbGFiX2dlbnVzX3NwcmVhZAoKcmVsYWJfZ2VudXNfSUQgPC0gbXV0YXRlKHJlbGFiX2dlbnVzX0lELCBTYW1wbGVJRCA9IHBhc3RlKFByb2JhbmQsIFRpbWUsIHNlcCA9Ii4iKSkKCnJvdy5uYW1lcyhyZWxhYl9nZW51c19JRCkgPC0gcmVsYWJfZ2VudXNfSUQkU2FtcGxlSUQKCkZBX3N0b29sLm8kUHJvYmFuZAoKRkFfc3Rvb2wubyA8LSBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLm8sICFQcm9iYW5kID09ICIzNFdGIiwhUHJvYmFuZCA9PSAiNDlSSiIpKQoKRkFfc3Rvb2wubyA8LSBtdXRhdGUoRkFfc3Rvb2wubywgU2FtcGxlSUQxID0gcGFzdGUoUHJvYmFuZCwgVGltZSwgc2VwID0gIi4iKSkKCnJvdy5uYW1lcyhGQV9zdG9vbC5vKSA8LSBGQV9zdG9vbC5vJFNhbXBsZUlEMQoKY29tbW9uLmlkcy5yZWxhYiA8LSBpbnRlcnNlY3Qocm93bmFtZXMoRkFfc3Rvb2wubyksIHJvd25hbWVzKHJlbGFiX3BoeWx1bV9JRCkpCgpGQV9zdG9vbC5vIDwtIEZBX3N0b29sLm9bY29tbW9uLmlkcy5yZWxhYixdCgpyZWxhYl9waHlsdW1fSUQgPC0gcmVsYWJfcGh5bHVtX0lEW2NvbW1vbi5pZHMucmVsYWIsXQoKcmVsYWJfZ2VudXNfSUQgPC0gcmVsYWJfZ2VudXNfSURbY29tbW9uLmlkcy5yZWxhYixdCgpgYGAKUGh5bHVtLUxldmVsIGxvZyB0cmFuc2Zvcm1hdGlvbiBoaW56dWZ1ZWdlbiB2b24gUHNldWRvY291bnQgdm9uIDAuMDAwMDEKCmBgYHtyfQpyZWxhYl9waHlsdW1fSURfbG9nIDwtIHJlbGFiX3BoeWx1bV9JRFssYygzOjgpXSArIDAuMDAwMDEKCnJlbGFiX3BoeWx1bV9JRF9sb2cgPC0gbG9nMTAocmVsYWJfcGh5bHVtX0lEX2xvZykKCnBoeWx1bV9GQSA8LSBjYmluZChyZWxhYl9waHlsdW1fSURfbG9nLCBGQV9zdG9vbC5vWywgYygyOjIzKV0pCmBgYAoKTG9vcCBLb3JyZWxhdGlvbiBmYWVrYWxlIExpbm9sZW5zYWV1cmUgdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX3BoeWx1bV9vbWVnYTZmIDwtIGZpbHRlcihwaHlsdW1fRkEsICFpcy5uYShMaW5vbHNhZXVyZV9mKSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmYgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CiAgCiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9waHlsdW1fb21lZ2E2ZiwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRMaW5vbHNhZXVyZV9mCgogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRMaW5vbHNhZXVyZV9mCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRMaW5vbHNhZXVyZV9mCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZmKSsxCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2Zltucm93LCJGQSJdIDwtICJMaW5vbGVpYyBmYSIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZmW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZmW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2Zltucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZmW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZmW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2Zltucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZmW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZmJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2ZiRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZmJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmYkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmYkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmYkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfUGh5bHVtX29tZWdhNmYgPC0gZmlsdGVyKGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmYsIHAuYWRqdXN0ZWQgPCAwLjA1IHwgcC5hZGp1c3RlZF9QUkUgPCAwLjA1IHwgcC5hZGp1c3RlZF9QT1NUIDwgMC4wNSkKCmBgYAoKUGxvdHRlbiB2b24gZmFla2FsZXIgT21lZ2E2IEZBIHVuZCBQaHlsdW0tbGV2ZWwgS29ycmVsYXRpb25lbgoKCmBgYHtyfQpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLCB4PUxpbm9sc2FldXJlX2YpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVpYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dzY2F0dGVyKHBoeWx1bV9GQSwgeD0nTGlub2xzYWV1cmVfZicsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknLGxhYmVsID0gJ1Byb2JhbmQnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J0xpbm9sc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVpYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKZ2dzY2F0dGVyKHBoeWx1bV9GQSwgeD0nTGlub2xlbnNhZXVyZV9mJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLGNvci5jb2VmLmNvb3JkID1jKDAsIC0wLjgpLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSdMaW5vbGVuc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPWMoMCwgLTAuOCksIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J0xpbm9sc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J0xpbm9sZW5zYWV1cmVfZicsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMsIHg9TGlub2xzYWV1cmVfZikpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fRmlybWljdXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYSwgeD1MaW5vbHNhZXVyZV9mKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYSwgeD1MaW5vbHNhZXVyZV9mKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEsIHg9TGlub2xzYWV1cmVfZikpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVmVycnVjb21pY3JvYmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCgpgYGAKCkxvb3AgTGlub2xlbnNhZXVyZSB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX29tZWdhM2YgPC0gZmlsdGVyKHBoeWx1bV9GQSwgIWlzLm5hKExpbm9sc2FldXJlX2YpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzZiA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBwaHlsdW1fY29sbmFtZXMpIHsKIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX29tZWdhM2YsICFpcy5uYShpKSkKIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRMaW5vbGVuc2FldXJlX2YKCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCgogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRMaW5vbGVuc2FldXJlX2YKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJExpbm9sZW5zYWV1cmVfZgogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCgogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmYpKzEKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNmW25yb3csIkZBIl0gPC0gIkxpbm9sZW5pYyBmYSIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNmW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNmW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzZltucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNmW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNmW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzZltucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNmW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzZiRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2YkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2YkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzZiRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzZiRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzZiRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmBgYAoKUGxvdHRlbiB2b24gS29ycmVsYXRpb25lbiB6d2lzY2hlbiBPbWVnYTMtRkEgdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9CmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMsIHg9TGlub2xlbnNhZXVyZV9mKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSdMaW5vbGVuc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScsbGFiZWw9J1Byb2JhbmQnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLCB4PUxpbm9sZW5zYWV1cmVfZikpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0Zpcm1pY3V0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEsIHg9TGlub2xlbnNhZXVyZV9mKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKCgpgYGAKCkxvb3AgT21lZ2E2IEF1Zm5haG1lIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9waHlsdW1fb21lZ2E2aSA8LSBmaWx0ZXIocGh5bHVtX0ZBLCAhaXMubmEoTGlub2xzYWV1cmVfaSkpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZpIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX29tZWdhNmksICFpcy5uYShpKSkKCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJExpbm9sc2FldXJlX2kKIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQoKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRMaW5vbHNhZXVyZV9pCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJExpbm9sc2FldXJlX2kKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmkpKzEKIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmlbbnJvdywiRkEiXSA8LSAiTGlub2xlaWMgZmEgaSIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZpW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZpW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2aVtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZpW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZpW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2aVtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZpW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2aSRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmkkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2aSRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZpJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZpJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZpJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKYGBgCgpQbG90dGVuIHZvbiBLb3JyZWxhdGlvbmVuIHp3aXNjaGVuIE9tZWdhNiBBdWZuYWhtZSB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KcGh5bHVtX0ZBJFRpbWUgPC0gZmFjdG9yKHBoeWx1bV9GQSRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEsIHg9TGlub2xzYWV1cmVfaSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBpbnRha2UgW2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J0xpbm9sc2FldXJlX2knLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGludGFrZSBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJywgbGFiZWwgPSAnUHJvYmFuZCcpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLCB4PUxpbm9sc2FldXJlX2kpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVpYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gaW50YWtlIFtnXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcywgeD1MaW5vbHNhZXVyZV9pKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGludGFrZSBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKYGBgCgpMb29wIE9tZWdhMyBBdWZuYWhtZSB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX29tZWdhM2kgPC0gZmlsdGVyKHBoeWx1bV9GQSwgIWlzLm5hKExpbm9sZW5zYWV1cmVfaSkpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNpIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewoKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9vbWVnYTNpLCAhaXMubmEoaSkpCiAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkTGlub2xlbnNhZXVyZV9pCgogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkTGlub2xlbnNhZXVyZV9pCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCgogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkTGlub2xlbnNhZXVyZV9pCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2kpKzEKIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2lbbnJvdywiRkEiXSA8LSAiTGlub2xlbmljIGZhIGkiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzaVtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzaVtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2lbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzaVtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzaVtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2lbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzaVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2kkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNpJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2kkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzaSRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzaSRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzaSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmBgYAoKUGxvdHRlbiBPbWVnYTMgQXVmbmFobWUgdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9CmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLCB4PUxpbm9sZW5zYWV1cmVfaSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gaW50YWtlIFtnXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSdMaW5vbGVuc2FldXJlX2knLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBpbnRha2UgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScsbGFiZWwgPSAnUHJvYmFuZCcpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLCB4PUxpbm9sZW5zYWV1cmVfaSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gaW50YWtlIFtnXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcywgeD1MaW5vbGVuc2FldXJlX2kpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGludGFrZSBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKCmBgYAoKTG9vcCBPbWVnYTMgRkEgQWJzb3JwdGlvbiBpbiBnCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX29tZWdhM2EgPC0gZmlsdGVyKHBoeWx1bV9GQSwgIWlzLm5hKEFfTGlub2xlbnNhZXVyZSkpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9waHlsdW1fb21lZ2EzYSwgIWlzLm5hKGkpKQoKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkQV9MaW5vbGVuc2FldXJlCiAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkQV9MaW5vbGVuc2FldXJlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJEFfTGlub2xlbnNhZXVyZQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzYSkrMQogCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzYVtucm93LCJGQSJdIDwtICJMaW5vbGVuaWMgZmEgYm9keSBpIgogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzYSRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2EkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2EkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2EkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpgYGAKClBsb3R0ZW4gdm9uIE9tZWdhMyBBdWZuYWhtZSBpbiBnIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYSwgeD1BX0xpbm9sZW5zYWV1cmUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGludGFrZSBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEsIHg9QV9MaW5vbGVuc2FldXJlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBpbnRha2UgW2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzLCB4PUFfTGlub2xlbnNhZXVyZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gaW50YWtlIFtnXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCmBgYAoKTG9vcCBPbWVnYTMgQXVzc2NoZWlkdW5nc3JhdGUgaW4gUHJvemVudCB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX29tZWdhM2FyIDwtIGZpbHRlcihwaHlsdW1fRkEsICFpcy5uYShBUl9MaW5vbGVuc2FldXJlKSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FyIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewoKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9vbWVnYTNhciwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRBUl9MaW5vbGVuc2FldXJlCgogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJEFSX0xpbm9sZW5zYWV1cmUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkQVJfTGlub2xlbnNhZXVyZQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhcikrMQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FyW25yb3csIkZBIl0gPC0gIkxpbm9sZW5pYyBmYSBQcmVjaXBpdGF0aW9uIgogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FyW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhcltucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FyW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FyW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhcltucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FyW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FyW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzYXIkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhciRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhciRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhciRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzYXIkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FyJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCmBgYAoKUGxvdHRlbiBPbWVnYTMgQXVzc2NoZWlkdW5nc3JhdGUgaW4gUHJvemVudCB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEsIHg9QVJfTGlub2xlbnNhZXVyZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIFByZWNpcGl0YXRpb24gcmF0ZSBbJV0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEsIHg9QVJfTGlub2xlbnNhZXVyZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIFByZWNpcGl0YXRpb24gcmF0ZSBbJV0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcywgeD1BUl9MaW5vbGVuc2FldXJlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlbmljIGZhdHR5IGFjaWQgUHJlY2lwaXRhdGlvbiByYXRlIFslXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J0FSX0xpbm9sZW5zYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBleGNyZXRpb24gcmF0ZSBbJV0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fRmlybWljdXRlcyknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLCB4PUFSX0xpbm9sZW5zYWV1cmUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVuaWMgZmF0dHkgYWNpZCBQcmVjaXBpdGF0aW9uIHJhdGUgWyVdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLCB4PUFSX0xpbm9sZW5zYWV1cmUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVuaWMgZmF0dHkgYWNpZCBQcmVjaXBpdGF0aW9uIHJhdGUgWyVdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dzY2F0dGVyKHBoeWx1bV9GQSwgeD0nQVJfTGlub2xlbnNhZXVyZScsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIGV4Y3JldGlvbiByYXRlIFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fRkEsIHg9J0FSX0xpbm9sZW5zYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgZXhjcmV0aW9uIHJhdGUgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmBgYAoKTG9vcCBPbWVnYTYgQXVzc2NoZWlkdW5nc3JhdGUgaW4gUHJvemVudCB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEsIHg9QVJfTGlub2xzYWV1cmUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVpYyBmYXR0eSBhY2lkIFByZWNpcGl0YXRpb24gcmF0ZSBbJV0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEsIHg9QVJfTGlub2xzYWV1cmUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVpYyBmYXR0eSBhY2lkIFByZWNpcGl0YXRpb24gcmF0ZSBbJV0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dzY2F0dGVyKHBoeWx1bV9GQSwgeD0nQVJfTGlub2xlbnNhZXVyZScsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIGV4Y3JldGlvbiByYXRlIFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScsbGFiZWw9ICdQcm9iYW5kJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcywgeD1BUl9MaW5vbHNhZXVyZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZWljIGZhdHR5IGFjaWQgUHJlY2lwaXRhdGlvbiByYXRlIFslXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEsIHg9QVJfTGlub2xzYWV1cmUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVpYyBmYXR0eSBhY2lkIFByZWNpcGl0YXRpb24gcmF0ZSBbJV0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVmVycnVjb21pY3JvYmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMsIHg9QVJfTGlub2xzYWV1cmUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVpYyBmYXR0eSBhY2lkIFByZWNpcGl0YXRpb24gcmF0ZSBbJV0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSdBUl9MaW5vbHNhZXVyZScsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgZXhjcmV0aW9uIHJhdGUgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMpJyxsYWJlbCA9ICdQcm9iYW5kJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVGVuZXJpY3V0ZXMsIHg9QVJfTGlub2xzYWV1cmUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVpYyBmYXR0eSBhY2lkIFByZWNpcGl0YXRpb24gcmF0ZSBbJV0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKCmBgYAoKTG9vcCBPbWVnYTYgQWJzb3JwdGlvbiBpbiBQcm96ZW50IHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9waHlsdW1fb21lZ2E2YXAgPC0gZmlsdGVyKHBoeWx1bV9GQSwgIWlzLm5hKEFQX0xpbm9sc2FldXJlKSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmFwIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewoKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9vbWVnYTZhcCwgIWlzLm5hKGkpKQogCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJEFQX0xpbm9sc2FldXJlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkQVBfTGlub2xzYWV1cmUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJEFQX0xpbm9sc2FldXJlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZhcCkrMQogCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2YXBbbnJvdywiRkEiXSA8LSAiTGlub2xlaWMgZmEgaSBbJV0iCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2YXBbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmFwW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2YXBbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2YXBbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmFwW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2YXBbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2YXBbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZhcCRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmFwJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmFwJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhNmFwJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTZhcCRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2E2YXAkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpgYGAKClBsb3R0ZW4gdm9uIE9tZWdhNiBBYnNvcnB0aW9uIGluIFByb3plbnQgdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9CmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLCB4PUFQX0xpbm9sc2FldXJlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlaWMgZmF0dHkgYWNpZCBpbnRha2UgcmF0ZSBbJV0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEsIHg9QVBfTGlub2xzYWV1cmUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVpYyBmYXR0eSBhY2lkIGludGFrZSByYXRlIFslXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLCB4PUFQX0xpbm9sc2FldXJlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlaWMgZmF0dHkgYWNpZCBQcmVjaXBpdGF0aW9uIHJhdGUgWyVdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0Zpcm1pY3V0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSwgeD1BUF9MaW5vbHNhZXVyZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZWljIGZhdHR5IGFjaWQgaW50YWtlIHJhdGUgWyVdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLCB4PUFQX0xpbm9sc2FldXJlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlaWMgZmF0dHkgYWNpZCBpbnRha2UgcmF0ZSBbJV0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcywgeD1BUl9MaW5vbHNhZXVyZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZWljIGZhdHR5IGFjaWQgUHJlY2lwaXRhdGlvbiByYXRlIFslXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpgYGAKCkxvb3AgT21lZ2EzIEFic29ycHRpb24gaW4gUHJvemVudCB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX29tZWdhM2FwIDwtIGZpbHRlcihwaHlsdW1fRkEsICFpcy5uYShBUF9MaW5vbGVuc2FldXJlKSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FwIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX29tZWdhM2FwLCAhaXMubmEoaSkpCiAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkQVBfTGlub2xlbnNhZXVyZQogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRBUF9MaW5vbGVuc2FldXJlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJEFQX0xpbm9sZW5zYWV1cmUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQoKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhcCkrMQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FwW25yb3csIkZBIl0gPC0gIkxpbm9sZW5pYyBmYSBpIFslXSIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhcFtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzYXBbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhcFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhcFtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzYXBbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhcFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhcFtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FwJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzYXAkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzYXAkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fb21lZ2EzYXAkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX29tZWdhM2FwJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9vbWVnYTNhcCRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmBgYAoKUGxvdHRlbiB2b24gT21lZ2EzIEFic29ycHRpb24gaW4gUHJvemVudCB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEsIHg9QVBfTGlub2xlbnNhZXVyZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZWljIGZhdHR5IGFjaWQgaW50YWtlIHJhdGUgWyVdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLCB4PUFQX0xpbm9sZW5zYWV1cmUpKSArIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVuaWMgZmF0dHkgYWNpZCBpbnRha2UgcmF0ZSBbJV0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcywgeD1BUF9MaW5vbGVuc2FldXJlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlbmljIGZhdHR5IGFjaWQgUHJlY2lwaXRhdGlvbiByYXRlIFslXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEsIHg9QVBfTGlub2xlbnNhZXVyZSkpICsgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZWljIGZhdHR5IGFjaWQgaW50YWtlIHJhdGUgWyVdJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLCB4PUFQX0xpbm9sZW5zYWV1cmUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdMaW5vbGVuaWMgZmF0dHkgYWNpZCBpbnRha2UgcmF0ZSBbJV0nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcywgeD1BUl9MaW5vbHNhZXVyZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0xpbm9sZWljIGZhdHR5IGFjaWQgUHJlY2lwaXRhdGlvbiByYXRlIFslXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpgYGAKCkxvb3AgRVBBIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQoKY29ycl9tYXBfcGh5bHVtX2VwYSA8LSBmaWx0ZXIocGh5bHVtX0ZBLCAhaXMubmEoRVBBX2kpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fZXBhIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewoKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9lcGEsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkRVBBX2kKIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJEVQQV9pCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJEVQQV9pCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fZXBhKSsxCgogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX2VwYVtucm93LCJGQSJdIDwtICJFUEEgaW50YWtlIFtnXSIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9lcGFbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX2VwYVtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX2VwYVtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9lcGFbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX2VwYVtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX2VwYVtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9lcGFbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9lcGEkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9lcGEkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX2VwYSRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9lcGEkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX2VwYSRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fZXBhJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKYGBgCgpQbG90dGVuIHZvbiBFUEEgdW5kIHBoeWx1bS1sZXZlbCAKCmBgYHtyfQpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSdFUEFfaScsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdFUEEgZmF0dHkgYWNpZCBpbnRha2UgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMpJyxsYWJlbD0gJ1Byb2JhbmQnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYSwgeD1FUEFfaSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yPSdncmV5NjUnKSArIHhsYWIoJ0VQQSBpbnRha2UgW2ddJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCgpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEsIHg9RVBBX2kpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdFUEEgaW50YWtlIFtnXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzLCB4PUVQQV9pKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignRVBBIGludGFrZSBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQpgYGAKCkxvb3AgREhBIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9waHlsdW1fZGhhIDwtIGZpbHRlcihwaHlsdW1fRkEsICFpcy5uYShESEFfaSkpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9kaGEgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9waHlsdW1fZGhhLCAhaXMubmEoaSkpCiAgCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJERIQV9pCiAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkREhBX2kKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJERIQV9pCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9kaGEpKzEKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9kaGFbbnJvdywiRkEiXSA8LSAiREhBIGludGFrZSBbZ10iCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fZGhhW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9kaGFbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9kaGFbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fZGhhW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9kaGFbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9kaGFbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fZGhhW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fZGhhJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fZGhhJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkgCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9kaGEkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fZGhhJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9kaGEkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX2RoYSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmBgYAoKUGxvdHRlbiB2b24gREhBIHVuZCBwaHlsdW0tbGV2ZWwgS29ycmVsYXRpb25lbgoKYGBge3J9CmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLCB4PURIQV9pKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignREhBIGludGFrZSBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fVGVuZXJpY3V0ZXMsIHg9REhBX2kpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdESEEgaW50YWtlIFtnXScpICsgCiAgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcyknKSsKICBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3NjYXR0ZXIocGh5bHVtX0ZBLCB4PSdESEFfaScsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdESEEgZmF0dHkgYWNpZCBpbnRha2UgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMpJyxsYWJlbD0gJ1Byb2JhbmQnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmBgYAoKTG9vcCBmYWVrYWxlcyBPbWVnYTYvT21lZ2EzLXJhdGlvIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQoKY29ycl9tYXBfcGh5bHVtX3JhIDwtIGZpbHRlcihwaHlsdW1fRkEsICFpcy5uYShyYXRpb19mKSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewoKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9yYSwgIWlzLm5hKGkpKQogCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJHJhdGlvX2YKICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJHJhdGlvX2YKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJHJhdGlvX2YKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhKSsxCiAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9yYVtucm93LCJGQSJdIDwtICJyYXRpbyBvbWVnYTYvb21lZ2EzIGZlY2FsIgogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9yYVtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9yYVtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fcmEkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9yYSRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9yYSRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9yYSRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fcmEkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3JhJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKYGBgCgpQbG90dGVuIHZvbiBmYWVrYWxlbSBPbWVnYTYvT21lZ2EzLXJhdGlvIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpnZ3Bsb3QocGh5bHVtX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYSwgeD1yYXRpb19mKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignb21lZ2EgNi9vbWVnYSAzIHJhdGlvIGZlY2FsJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCmdncGxvdChwaHlsdW1fRkEsIGFlcyh5PWtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLCB4PXJhdGlvX2YpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG9yPVRpbWUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZWxsb3dncmVlbicsICdjb3JhbDInKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvcj0nZ3JleTY1JykgKyB4bGFiKCdvbWVnYSA2L29tZWdhIDMgcmF0aW8gZmVjYWwnKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwbG90KHBoeWx1bV9GQSwgYWVzKHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcywgeD1yYXRpb19mKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1UaW1lKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygneWVsbG93Z3JlZW4nLCAnY29yYWwyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignb21lZ2EgNi9vbWVnYSAzIHJhdGlvIGZlY2FsJykgKyAKICB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0Zpcm1pY3V0ZXMpJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKCmBgYAoKR2VudXMtbGV2ZWwsIEZpbHRlcm4gZGVyIE1ldGFkYXRlbiwgbG9nIHRyYW5zZm9ybWF0aW9uIHVuZCBoaW56dWZ1ZWdlbiB2b24gUHNldWRvY291bnQgMC4wMDAwMQoKCmBgYHtyfQpnZW51c19jb2xuYW1lcyA8LSBjb2xuYW1lcyhyZWxhYl9nZW51c19zcHJlYWRbLCBjKDM6MzEpXSkKCnJlbGFiX2dlbnVzX0lEX2xvZyA8LSByZWxhYl9nZW51c19JRFssYygzOjMxKV0gKyAwLjAwMDAxCgpyZWxhYl9nZW51c19JRF9sb2cgPC0gbG9nMTAocmVsYWJfZ2VudXNfSURfbG9nKQoKZ2VudXNfRkEgPC0gY2JpbmQocmVsYWJfZ2VudXNfSURfbG9nLCBGQV9zdG9vbC5vKQpnZW51c19GQSRUaW1lIDwtIGZhY3RvcihnZW51c19GQSRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKCmBgYAoKCkxvb3AgZmFla2FsZSBPbWVnYTMgRkEgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfb21lZ2EzZiA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYShMaW5vbGVuc2FldXJlX2YpKQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNmIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19vbWVnYTNmLCAhaXMubmEoaSkpCiAgCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJExpbm9sZW5zYWV1cmVfZgogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRMaW5vbGVuc2FldXJlX2YKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJExpbm9sZW5zYWV1cmVfZgogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNmKSsxCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNmW25yb3csIkZBIl0gPSAiTGlub2xlbmljIGZhIGZlY2FsIgogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzZltucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2ZbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2ZbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNmW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2ZbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2ZbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNmW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNmJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNmJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzZiRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2YkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzZiRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNmJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKYGBgCgpQbG90dGVuIGZhZWthbGUgT21lZ2EzIEZBIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9Cmdnc2NhdHRlcihnZW51c19GQSwgeD0nTGlub2xlbnNhZXVyZV9tb2wnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtubW9sL2ddJywgY29yLmNvZWYuY29vcmQgPWMoMCwgLTEuOSksIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nTGlub2xlbnNhZXVyZV9tb2wnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtubW9sL2ddJywgY29yLmNvZWYuY29vcmQgPWMoMCwgLTEuOSksIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nTGlub2xzYWV1cmVfZicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJyxsYWJlbCA9ICdQcm9iYW5kJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKZ2dwbG90KGdlbnVzX0ZBLCBhZXMoeT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0VyeXNpcGVsb3RyaWNoaS5vX19FcnlzaXBlbG90cmljaGFsZXMuZl9fRXJ5c2lwZWxvdHJpY2hhY2VhZS5nX18uRXViYWN0ZXJpdW0uLCB4PUxpbm9sZW5zYWV1cmVfZikpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llbGxvd2dyZWVuJywgJ2NvcmFsMicsICdzdGVlbGJsdWUyJykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3I9J2dyZXk2NScpICsgeGxhYignTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nKSArIAogIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRXViYWN0ZXJpdW0pJykrCiAgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0xpbm9sZW5zYWV1cmVfZicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fRXJ5c2lwZWxvdHJpY2hpLm9fX0VyeXNpcGVsb3RyaWNoYWxlcy5mX19FcnlzaXBlbG90cmljaGFjZWFlLmdfXy5FdWJhY3Rlcml1bS4nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0V1YmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdMaW5vbGVuc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19Db3Jpb2JhY3RlcmlpYS5vX19Db3Jpb2JhY3RlcmlhbGVzLmZfX0NvcmlvYmFjdGVyaWFjZWFlLmdfX0NvbGxpbnNlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db2xsaW5zZWxsYScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdMaW5vbGVuc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19Db3Jpb2JhY3RlcmlpYS5vX19Db3Jpb2JhY3RlcmlhbGVzLmZfX0NvcmlvYmFjdGVyaWFjZWFlLmdfXycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZl9fQ29yaW9iYWN0ZXJpYWNlYWUnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nTGlub2xlbnNhZXVyZV9mJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19CYWNpbGxpLm9fX0xhY3RvYmFjaWxsYWxlcy5mX19TdHJlcHRvY29jY2FjZWFlLmdfX1N0cmVwdG9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N0cmVwdG9jb2NjdXMnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nTGlub2xlbnNhZXVyZV9mJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db3Byb2NvY2N1cycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdMaW5vbGVuc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fLlJ1bWlub2NvY2N1cy4nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1J1bWlub2NvY2N1cycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdMaW5vbGVuc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRmFlY2FsaWJhY3Rlcml1bScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCmBgYAoKCkxvb3AgZmFla2FsZSBPbWVnYTYtRkEgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfb21lZ2E2ZiA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYShMaW5vbHNhZXVyZV9mKSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2ZiA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBnZW51c19jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfZ2VudXNfb21lZ2E2ZiwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRMaW5vbHNhZXVyZV9mCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJExpbm9sZW5zYWV1cmVfZgogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkTGlub2xzYWV1cmVfZgogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZmKSsxCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZmW25yb3csIkZBIl0gPSAiTGlub2xlaWMgZmEgZmVjYWwiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZmW25yb3csICJHZW51cyJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2Zltucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2Zltucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmZbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2Zltucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2Zltucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmZbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmYkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmYkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZmJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2ZiRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZmJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmYkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpgYGAKClBsb3R0ZW4gZmFla2FsZSBPbWVnYTYtRkEgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KCmdnc2NhdHRlcihnZW51c19GQSwgeD0nTGlub2xzYWV1cmVfZicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0xpbm9sc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0VyeXNpcGVsb3RyaWNoaS5vX19FcnlzaXBlbG90cmljaGFsZXMuZl9fRXJ5c2lwZWxvdHJpY2hhY2VhZS5nX18uRXViYWN0ZXJpdW0uJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVpYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0V1YmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0xpbm9sc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19Db3Jpb2JhY3RlcmlpYS5vX19Db3Jpb2JhY3RlcmlhbGVzLmZfX0NvcmlvYmFjdGVyaWFjZWFlLmdfX0NvbGxpbnNlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVpYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvbGxpbnNlbGxhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0xpbm9sc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0JhY2lsbGkub19fTGFjdG9iYWNpbGxhbGVzLmZfX1N0cmVwdG9jb2NjYWNlYWUuZ19fU3RyZXB0b2NvY2N1cycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlaWMgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIGZlY2FsIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdHJlcHRvY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0xpbm9sc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQ29wcm9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29wcm9jb2NjdXMnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nTGlub2xzYWV1cmVfZicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVpYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nTGlub2xzYWV1cmVfZicsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVpYyBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gZmVjYWwgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0Fra2VybWFuc2lhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0xpbm9sc2FldXJlX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fLlJ1bWlub2NvY2N1cy4nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBmZWNhbCBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUnVtaW5vY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmBgYAoKTG9vcCBwcm96ZW50dWFsZSBBdXNzY2hlaWR1bmdzcmF0ZSBPbWVnYTMtRkEgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfb21lZ2EzYXIgPC0gZmlsdGVyKGdlbnVzX0ZBLCAhaXMubmEoQVJfTGlub2xlbnNhZXVyZSkpCgpjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FyIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19vbWVnYTNhciwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRBUl9MaW5vbGVuc2FldXJlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJEFSX0xpbm9sZW5zYWV1cmUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJEFSX0xpbm9sZW5zYWV1cmUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYXIpKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FyW25yb3csIkZBIl0gPSAiTGlub2xlbmljIGZhIFByZWNpcGl0YXRpb24gcmF0ZSAiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhcltucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FyW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhcltucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FyW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FyW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhcltucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FyW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhciRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYXIkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhciRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FyJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FyJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FyJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKYGBgCgoKUGxvdHRlbiBwcm96ZW50dWFsZSBBdXNzY2hlaWR1bmdzcmF0ZSBPbWVnYTMtRkEgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBUl9MaW5vbGVuc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgUHJlY2lwaXRhdGlvbiByYXRlIFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nQVJfTGlub2xlbnNhZXVyZScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19CbGF1dGlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBQcmVjaXBpdGF0aW9uIHJhdGUgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JsYXV0aWEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBUl9MaW5vbGVuc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19FcnlzaXBlbG90cmljaGkub19fRXJ5c2lwZWxvdHJpY2hhbGVzLmZfX0VyeXNpcGVsb3RyaWNoYWNlYWUuZ19fLkV1YmFjdGVyaXVtLicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgUHJlY2lwaXRhdGlvbiByYXRlIFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19FdWJhY3Rlcml1bScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBUl9MaW5vbGVuc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19CYWNpbGxpLm9fX0xhY3RvYmFjaWxsYWxlcy5mX19TdHJlcHRvY29jY2FjZWFlLmdfX1N0cmVwdG9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIFByZWNpcGl0YXRpb24gcmF0ZSBbJV0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3RyZXB0b2NvY2N1cycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBUl9MaW5vbGVuc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBQcmVjaXBpdGF0aW9uIHJhdGUgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0FSX0xpbm9sZW5zYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgUHJlY2lwaXRhdGlvbiByYXRlIFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmBgYAoKTG9vcCBwcm96ZW50dWFsZSBBdXNzY2hlaWR1bmdzcmF0ZSBPbWVnYTYtRkEgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfb21lZ2E2YXIgPC0gZmlsdGVyKGdlbnVzX0ZBLCAhaXMubmEoQVJfTGlub2xzYWV1cmUpKQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhciA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBnZW51c19jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfZ2VudXNfb21lZ2E2YXIsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkQVJfTGlub2xzYWV1cmUKICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkQVJfTGlub2xzYWV1cmUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJEFSX0xpbm9sc2FldXJlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFyKSsxCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhcltucm93LCJGQSJdID0gIkxpbm9sZWljIGZhIFByZWNpcGl0YXRpb24gcmF0ZSAiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhcltucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFyW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhcltucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFyW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFyW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhcltucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFyW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhciRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2YXIkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhciRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFyJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFyJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFyJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKYGBgCgoKUGxvdHRlbiBwcm96ZW50dWFsZSBPbWVnYTYgQXVzc2NoZWlkdW5nc3JhdGUgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KCmdnc2NhdHRlcihnZW51c19GQSwgeD0nQVJfTGlub2xzYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVpYyBmYXR0eSBhY2lkIFByZWNpcGl0YXRpb24gcmF0ZSBbJV0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0FSX0xpbm9sc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX1ByZXZvdGVsbGFjZWFlLmdfX1ByZXZvdGVsbGEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgUHJlY2lwaXRhdGlvbiByYXRlIFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19QcmV2b3RlbGxhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nQVJfTGlub2xzYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgUHJlY2lwaXRhdGlvbiByYXRlIFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CYWN0ZXJvaWRlcycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBUl9MaW5vbGVuc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0JsYXV0aWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIFByZWNpcGl0YXRpb24gcmF0ZSBbJV0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmxhdXRpYScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0FSX0xpbm9sc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19FcnlzaXBlbG90cmljaGkub19fRXJ5c2lwZWxvdHJpY2hhbGVzLmZfX0VyeXNpcGVsb3RyaWNoYWNlYWUuZ19fLkV1YmFjdGVyaXVtLicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlaWMgZmF0dHkgYWNpZCBQcmVjaXBpdGF0aW9uIHJhdGUgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0V1YmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0FSX0xpbm9sc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19CYWNpbGxpLm9fX0xhY3RvYmFjaWxsYWxlcy5mX19TdHJlcHRvY29jY2FjZWFlLmdfX1N0cmVwdG9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgUHJlY2lwaXRhdGlvbiByYXRlIFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdHJlcHRvY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0FSX0xpbm9sZW5zYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQ29wcm9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIFByZWNpcGl0YXRpb24gcmF0ZSBbJV0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29wcm9jb2NjdXMnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nQVJfTGlub2xzYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlaWMgZmF0dHkgYWNpZCBQcmVjaXBpdGF0aW9uIHJhdGUgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBUl9MaW5vbHNhZXVyZScsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19SaWtlbmVsbGFjZWFlLmdfXycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlaWMgZmF0dHkgYWNpZCBQcmVjaXBpdGF0aW9uIHJhdGUgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGZfX1Jpa2VuZWxsYWNlYWUnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBUl9MaW5vbHNhZXVyZScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlaWMgZmF0dHkgYWNpZCBQcmVjaXBpdGF0aW9uIHJhdGUgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RvcmVhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpgYGAKCkxvb3AgYWJzb3JiaWVydGUgT21lZ2EzLUZBIGluIGcgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfb21lZ2EzYSA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYShBX0xpbm9sZW5zYWV1cmUpKQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19vbWVnYTNhLCAhaXMubmEoaSkpCiAgCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJEFfTGlub2xlbnNhZXVyZQogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRBX0xpbm9sZW5zYWV1cmUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJEFfTGlub2xlbnNhZXVyZQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhKSsxCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhW25yb3csIkZBIl0gPSAiTGlub2xlbmljIGZhIGludGFrZSBpbnRvIHRoZSBib2R5ICIKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FbbnJvdywgIkdlbnVzIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYVtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYSRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYSRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2EkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2EkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpgYGAKClBsb3R0ZW4gYWJzb3JiaWVydGUgT21lZ2EzLUZBIGluIGcgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KCmdnc2NhdHRlcihnZW51c19GQSwgeD0nQV9MaW5vbGVuc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgUHJlY2lwaXRhdGlvbiByYXRlIFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nQV9MaW5vbGVuc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX1ByZXZvdGVsbGFjZWFlLmdfX1ByZXZvdGVsbGEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIGFic29yYmVkIGludG8gdGhlIGJvZHkgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1ByZXZvdGVsbGEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBX0xpbm9sZW5zYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIGFic29yYmVkIGludG8gdGhlIGJvZHkgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JhY3Rlcm9pZGVzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nQV9MaW5vbGVuc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfXy5CYXJuZXNpZWxsYWNlYWUuLmdfXycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgYWJzb3JiZWQgaW50byB0aGUgYm9keSBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZl9fQmFybmVzaWVsbGFjZWFlJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nQV9MaW5vbGVuc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0xhY2hub3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBhYnNvcmJlZCBpbnRvIHRoZSBib2R5IFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19MYWNobm9zcGlyYScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBX0xpbm9sZW5zYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19Db3Jpb2JhY3RlcmlpYS5vX19Db3Jpb2JhY3RlcmlhbGVzLmZfX0NvcmlvYmFjdGVyaWFjZWFlLmdfX0NvbGxpbnNlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVuaWMgZmF0dHkgYWNpZCBhYnNvcmJlZCBpbnRvIHRoZSBib2R5IFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db2xsaW5zZWxsYScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKYGBgCgpMb29wIGFic29yYmllcnRlIE9tZWdhNi1GQSBpbiBnIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX29tZWdhNmEgPC0gZmlsdGVyKGdlbnVzX0ZBLCAhaXMubmEoQV9MaW5vbHNhZXVyZSkpCgpjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmEgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX29tZWdhNmEsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkQV9MaW5vbHNhZXVyZQogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRBX0xpbm9sc2FldXJlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRBX0xpbm9sc2FldXJlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmEpKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFbbnJvdywiRkEiXSA9ICJMaW5vbGVpYyBmYSBpbnRha2UgaW50byB0aGUgYm9keSAiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhW25yb3csICJHZW51cyJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2YVtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2YVtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2YVtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2YVtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmEkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmEkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2YSRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCmNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2YSRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKYGBgCgpQbG90dGVuIGFic29yYmllcnRlIE9tZWdhNi1GQSBpbiBnIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9Cmdnc2NhdHRlcihnZW51c19GQSwgeD0nQV9MaW5vbHNhZXVyZScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19QaGFzY29sYXJjdG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgYWJzaW9yYmVkIGludG8gdGhlIGJvZHkgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1BoYXNjb2xhcmN0b2JhY3Rlcml1bScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0FfTGlub2xzYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fLlJ1bWlub2NvY2N1cy4nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgYWJzaW9yYmVkIGludG8gdGhlIGJvZHkgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1J1bWlub2NvY2N1cycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0FfTGlub2xzYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgYWJzaW9yYmVkIGludG8gdGhlIGJvZHkgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RvcmVhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nQV9MaW5vbHNhZXVyZScsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19QcmV2b3RlbGxhY2VhZS5nX19QcmV2b3RlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVpYyBmYXR0eSBhY2lkIGFic29yYmVkIGludG8gdGhlIGJvZHkgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1ByZXZvdGVsbGEnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBX0xpbm9sc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX0JhY3Rlcm9pZGFjZWFlLmdfX0JhY3Rlcm9pZGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVpYyBmYXR0eSBhY2lkIGFic29yYmVkIGludG8gdGhlIGJvZHkgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JhY3Rlcm9pZGVzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nQV9MaW5vbHNhZXVyZScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19EaWFsaXN0ZXInLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgYWJzb3JiZWQgaW50byB0aGUgYm9keSBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKYGBgCgpMb29wIHByb3plbnR1YWxlIE9tZWdhMy1GQSBBYnNvcnB0aW9uIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9Cgpjb3JyX21hcF9nZW51c19vbWVnYTNhcCA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYShBUF9MaW5vbGVuc2FldXJlKSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYXAgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX29tZWdhM2FwLCAhaXMubmEoaSkpCiAgCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJEFQX0xpbm9sZW5zYWV1cmUKICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkQVBfTGlub2xlbnNhZXVyZQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkQVBfTGlub2xlbnNhZXVyZQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhcCkrMQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYXBbbnJvdywiRkEiXSA9ICJMaW5vbGVuaWMgZmEgaW50YWtlIGludG8gdGhlIGJvZHkgWyVdICIKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FwW25yb3csICJHZW51cyJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYXBbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FwW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYXBbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYXBbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FwW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYXBbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FwJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhcCRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FwJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2EzYXAkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCgpjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FwJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhM2FwJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKYGBgCgpQbG90dGVuIHByb3plbnR1YWxlIE9tZWdhMy1GQSBBYnNvcnB0aW9uIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9Cmdnc2NhdHRlcihnZW51c19GQSwgeD0nQVBfTGlub2xlbnNhZXVyZScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIGFic29yYmVkIGludG8gdGhlIGJvZHkgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBUF9MaW5vbGVuc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19FcnlzaXBlbG90cmljaGkub19fRXJ5c2lwZWxvdHJpY2hhbGVzLmZfX0VyeXNpcGVsb3RyaWNoYWNlYWUuZ19fLkV1YmFjdGVyaXVtLicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgYWJzb3JiZWQgaW50byB0aGUgYm9keSBbJV0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRXViYWN0ZXJpdW0nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBUF9MaW5vbGVuc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgYWJzb3JiZWQgaW50byB0aGUgYm9keSBbJV0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZl9fTGFjaG5vc3BpcmFjZWFlJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBUF9MaW5vbGVuc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19CYWNpbGxpLm9fX0xhY3RvYmFjaWxsYWxlcy5mX19TdHJlcHRvY29jY2FjZWFlLmdfX1N0cmVwdG9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIGFic29yYmVkIGludG8gdGhlIGJvZHkgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N0cmVwdG9jb2NjdXMnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0FQX0xpbm9sZW5zYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQ29wcm9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZW5pYyBmYXR0eSBhY2lkIGFic29yYmVkIGludG8gdGhlIGJvZHkgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0FQX0xpbm9sZW5zYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlbmljIGZhdHR5IGFjaWQgYWJzb3JiZWQgaW50byB0aGUgYm9keSBbJV0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRmFlY2FsaWJhY3Rlcml1bScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpgYGAKCkxvb3AgcHJvemVudHVhbGUgT21lZ2E2LUZBIEFic29ycHRpb24gdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfb21lZ2E2YXAgPC0gZmlsdGVyKGdlbnVzX0ZBLCAhaXMubmEoQVBfTGlub2xzYWV1cmUpKQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhcCA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBnZW51c19jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfZ2VudXNfb21lZ2E2YXAsICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkQVBfTGlub2xzYWV1cmUKICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkQVBfTGlub2xzYWV1cmUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJEFQX0xpbm9sc2FldXJlCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFwKSsxCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhcFtucm93LCJGQSJdID0gIkxpbm9sZWljIGZhIGludGFrZSBpbnRvIHRoZSBib2R5IFslXSAiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhcFtucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFwW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhcFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFwW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFwW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhcFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFwW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhcCRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2E2YXAkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTZhcCRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhNmFwJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhcCRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYTNhcCRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmBgYAoKClBsb3R0ZW4gcHJvemVudHVhbGUgT21lZ2E2LUZBIEFic29ycHRpb24gdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBUF9MaW5vbHNhZXVyZScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xpbm9sZWljIGZhdHR5IGFjaWQgYWJzb3JiZWQgaW50byB0aGUgYm9keSBbJV0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0FQX0xpbm9sc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19FcnlzaXBlbG90cmljaGkub19fRXJ5c2lwZWxvdHJpY2hhbGVzLmZfX0VyeXNpcGVsb3RyaWNoYWNlYWUuZ19fLkV1YmFjdGVyaXVtLicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlaWMgZmF0dHkgYWNpZCBhYnNvcmJlZCBpbnRvIHRoZSBib2R5IFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19FdWJhY3Rlcml1bScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0FQX0xpbm9sc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX0JhY3Rlcm9pZGFjZWFlLmdfX0JhY3Rlcm9pZGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVpYyBmYXR0eSBhY2lkIGFic29yYmVkIGludG8gdGhlIGJvZHkgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JhY3Rlcm9pZGVzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nQVBfTGlub2xzYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0JhY2lsbGkub19fTGFjdG9iYWNpbGxhbGVzLmZfX1N0cmVwdG9jb2NjYWNlYWUuZ19fU3RyZXB0b2NvY2N1cycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlaWMgZmF0dHkgYWNpZCBhYnNvcmJlZCBpbnRvIHRoZSBib2R5IFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdHJlcHRvY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdBUF9MaW5vbHNhZXVyZScsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVpYyBmYXR0eSBhY2lkIGFic29yYmVkIGludG8gdGhlIGJvZHkgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0Fra2VybWFuc2lhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0FQX0xpbm9sc2FldXJlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0RvcmVhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMaW5vbGVpYyBmYXR0eSBhY2lkIGFic29yYmVkIGludG8gdGhlIGJvZHkgWyVdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RvcmVhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nQVBfTGlub2xzYWV1cmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTGlub2xlaWMgZmF0dHkgYWNpZCBhYnNvcmJlZCBpbnRvIHRoZSBib2R5IFslXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpgYGAKCkxvb3AgRVBBLUF1Zm5haG1lIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX29tZWdhZXBhIDwtIGZpbHRlcihnZW51c19GQSwgIWlzLm5hKEVQQV9pKSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2FlcGEgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX29tZWdhZXBhLCAhaXMubmEoaSkpCiAgCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJEVQQV9pCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJEVQQV9pCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRFUEFfaQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWVwYSkrMQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2FlcGFbbnJvdywiRkEiXSA9ICJFUEEgaW50YWtlIFtnXSAiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWVwYVtucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhZXBhW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWVwYVtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhZXBhW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhZXBhW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWVwYVtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhZXBhW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWVwYSRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2FlcGEkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWVwYSRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhZXBhJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWVwYSRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWVwYSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmBgYAoKUGxvdHRlbiB2b24gRVBBLUF1Zm5haG1lIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0VQQV9pJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19FcnlzaXBlbG90cmljaGkub19fRXJ5c2lwZWxvdHJpY2hhbGVzLmZfX0VyeXNpcGVsb3RyaWNoYWNlYWUuZ19fLkV1YmFjdGVyaXVtLicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnRVBBIGZhdHR5IGFjaWQgaW50YWtlIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19FdWJhY3Rlcml1bScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0VQQV9pJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX0JhY3Rlcm9pZGFjZWFlLmdfX0JhY3Rlcm9pZGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdFUEEgZmF0dHkgYWNpZCBpbnRha2UgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JhY3Rlcm9pZGVzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgoKCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdFUEFfaScsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdFUEEgZmF0dHkgYWNpZCBpbnRha2UgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0Fra2VybWFuc2lhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0VQQV9pJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXy5SdW1pbm9jb2NjdXMuJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdFUEEgZmF0dHkgYWNpZCBpbnRha2UgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1J1bWlub2NvY2N1cycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdFUEFfaScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19QaGFzY29sYXJjdG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0VQQSBmYXR0eSBhY2lkIGludGFrZSBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUGhhc2NvbGFyY3RvYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nRVBBX2knLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19WZWlsbG9uZWxsYWNlYWUuZ19fRGlhbGlzdGVyJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdFUEEgZmF0dHkgYWNpZCBpbnRha2UgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpgYGAKCgpMb29wIERIQS1BdWZuYWhtZSB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9nZW51c19vbWVnYWRoYSA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYShESEFfaSkpCgpjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhZGhhIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19vbWVnYWRoYSwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRESEFfaQogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRESEFfaQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkREhBX2kKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2FkaGEpKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhZGhhW25yb3csIkZBIl0gPSAiREhBIGludGFrZSBbZ10gIgogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2FkaGFbbnJvdywgIkdlbnVzIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWRoYVtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2FkaGFbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWRoYVtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWRoYVtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2FkaGFbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWRoYVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2FkaGEkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX29tZWdhZGhhJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2FkaGEkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19vbWVnYWRoYSRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCmNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2FkaGEkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfb21lZ2FkaGEkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpgYGAKClBsb3R0ZW4gREhBLUF1Zm5haG1lIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9Cmdnc2NhdHRlcihnZW51c19GQSwgeD0nREhBX2knLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0VyeXNpcGVsb3RyaWNoaS5vX19FcnlzaXBlbG90cmljaGFsZXMuZl9fRXJ5c2lwZWxvdHJpY2hhY2VhZS5nX18uRXViYWN0ZXJpdW0uJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdESEEgZmF0dHkgYWNpZCBpbnRha2UgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0V1YmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nREhBX2knLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQmxhdXRpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnREhBIGZhdHR5IGFjaWQgaW50YWtlIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CbGF1dGlhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nREhBX2knLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0RIQSBmYXR0eSBhY2lkIGludGFrZSBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmFjdGVyb2lkZXMnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nREhBX2knLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fLlJ1bWlub2NvY2N1cy4nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0RIQSBmYXR0eSBhY2lkIGludGFrZSBbZ10nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUnVtaW5vY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0nREhBX2knLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19WZWlsbG9uZWxsYWNlYWUuZ19fUGhhc2NvbGFyY3RvYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdESEEgZmF0dHkgYWNpZCBpbnRha2UgW2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1BoYXNjb2xhcmN0b2JhY3Rlcml1bScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J0RIQV9pJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fVmVpbGxvbmVsbGFjZWFlLmdfX0RpYWxpc3RlcicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnREhBIGZhdHR5IGFjaWQgaW50YWtlIFtnXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDkwKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgoKYGBgCgpMb29wIGbDpGthbGVzIE9tZWdhNi9PbWVnYTMtcmF0aW8gdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfcmEgPC0gZmlsdGVyKGdlbnVzX0ZBLCAhaXMubmEocmF0aW9fZikpCgpjb3JyX3NwZWFybWFuX2dlbnVzX3JhIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19yYSwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRyYXRpb19mCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJHJhdGlvX2YKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJHJhdGlvX2YKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfcmEpKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3JhW25yb3csIkZBIl0gPSAib21lZ2E2L29tZWdhMyByYXRpbyAiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19yYVtucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3JhW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19yYVtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3JhW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3JhW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c19yYVtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3JhW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c19yYSRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfcmEkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c19yYSRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX3JhJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zcGVhcm1hbl9nZW51c19yYSRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19yYSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmBgYAoKUGxvdHRlbiBPbWVnYTYvT21lZ2EzLXJhdGlvIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J3JhdGlvX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdvbWVnYSA2L29tZWdhIDMgcmF0aW8gZmVjYWwnLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKCmdnc2NhdHRlcihnZW51c19GQSwgeD0ncmF0aW9fZicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19MYWNobm9zcGlyYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnb21lZ2EgNi9vbWVnYSAzIHJhdGlvIGZlY2FsJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0xhY2hub3NwaXJhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdyYXRpb19mJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX0JhY3Rlcm9pZGFjZWFlLmdfX0JhY3Rlcm9pZGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdvbWVnYSA2L29tZWdhIDMgcmF0aW8gZmVjYWwnLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmFjdGVyb2lkZXMnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdyYXRpb19mJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQ29yaW9iYWN0ZXJpaWEub19fQ29yaW9iYWN0ZXJpYWxlcy5mX19Db3Jpb2JhY3RlcmlhY2VhZS5nX19Db2xsaW5zZWxsYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnb21lZ2EgNi9vbWVnYSAzIHJhdGlvIGZlY2FsJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvbGxpbnNlbGxhJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgoKZ2dzY2F0dGVyKGdlbnVzX0ZBLCB4PSdyYXRpb19mJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXy5SdW1pbm9jb2NjdXMuJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdvbWVnYSA2L29tZWdhIDMgcmF0aW8gZmVjYWwnLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUnVtaW5vY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3NjYXR0ZXIoZ2VudXNfRkEsIHg9J3JhdGlvX2YnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19WZWlsbG9uZWxsYWNlYWUuZ19fUGhhc2NvbGFyY3RvYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdvbWVnYSA2L29tZWdhIDMgcmF0aW8gZmVjYWwnLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUGhhc2NvbGFyY3RvYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gOTApKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdnc2NhdHRlcihnZW51c19GQSwgeD0ncmF0aW9fZicsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ29tZWdhIDYvb21lZ2EgMyByYXRpbyBmZWNhbCcsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CaWZpZG9iYWN0ZXJpdW0nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA5MCkpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmBgYAoKNC4gU8OkdHRpZ3VuZ3N0eXBlbgpFaW50ZWlsdW5nIGRlciBTw6R0dGlndW5nc3R5cGVuIG5hY2ggZsOka2FsZXIgRmV0dHPDpHVyZXPDpHR0aWd1bmc6IHNhdCwgdW5zYXQsIGNoYW5nZS5zYXQsIGNoYW5nZS51bnNhdApMYWRlbiBkZXIgTWV0YWRhdGVuClZlcmdsZWljaCBkZXIgQXVmbmFobWUgdm9uIEZldHRzw6R1cmVuIMO8YmVyIE5haHJ1bmcgendpc2NoZW4gZGVuIFPDpHR0aWd1bmdzdHlwZW4KCmBgYHtyfQpGQV9zdG9vbC5TVCA8LSByZWFkLnRhYmxlKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mYSBzYXR1cmF0aW9uIG1pdCBpbnRha2UgdHlwZXMudHh0Iiwgc2VwID0gJ1x0JywgY29tbWVudD0nJywKICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkPVQpCgpWaWV3KEZBX3N0b29sLlNUKQoKRkFfc3Rvb2wuU1QkVGltZSA8LWZhY3RvcihGQV9zdG9vbC5TVCRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKcm93Lm5hbWVzKEZBX3N0b29sLlNUKSA8LSBGQV9zdG9vbC5TVCRTYW1wbGVJRAoKRkFfc3Rvb2wuU1QkUHJvYmFuZAoKRkFfc3Rvb2wuU1QgPC0gc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgIVNhbXBsZUlEID09ICJTVC4zNUFELjBVMSIpKQoKRkFfc3Rvb2wuU1QgPC0gc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgIVByb2JhbmQgPT0gIjMzTVAiLCAhUHJvYmFuZCA9PSAiMzVBRCIsICFQcm9iYW5kID09ICIzNFdGIiwgIVByb2JhbmQgPT0gIjQ5UkoiKSkKCmNvbXBhcmlzb25fc2F0IDwtIGxpc3QoYygic2F0IiwgInVuc2F0IikpCgpjb21wYXJpc29uX2NoYW5nZSA8LSBsaXN0KGMoImNoYW5nZS5zYXQiLCAiY2hhbmdlLnVuc2F0IikpCgpjb21wYXJpc29uX3RpbWUgPC0gbGlzdChjKCJQUkUiLCAiUE9TVCIpKQpgYGAKCktvcnJlbGF0aW9uZW4gZHVyY2ggZGllIE5haHJ1bmcgYXVmZ2Vub21tZW5lIHVuZ2Vzw6R0dGlndGUgRkEgbWl0IGbDpGthbGVuIHVuZ2Vzw6R0dGlndGVuIEZBCgpgYGB7cn0Kc3Rvb2wubWVsdC51bnNhdCA8LSBtZWx0KEZBX3N0b29sLlNULCBpZC52YXJzID0gYygnVGltZScsJ1Byb2JhbmQnKSwgbWVhc3VyZS52YXJzID0gYygndW5zYXQnLCAndW5zYXQuaScpKQoKc3Rvb2wubWVsdC51bnNhdDwtIGRwbHlyOjpyZW5hbWUoc3Rvb2wubWVsdC51bnNhdCwgRkE9dmFyaWFibGUpCnN0b29sLm1lbHQudW5zYXQ8LSBkcGx5cjo6cmVuYW1lKHN0b29sLm1lbHQudW5zYXQsIENvbmNlbnRyYXRpb249dmFsdWUpCgpzdG9vbC5tZWx0LnVuc2F0JFRpbWUgPC0gZmFjdG9yKHN0b29sLm1lbHQudW5zYXQkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCgpnZ3BhaXJlZChzdG9vbC5tZWx0LnVuc2F0LCB4PSdGQScsIHk9J0NvbmNlbnRyYXRpb24nLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywnd2hpdGVzbW9rZScpLCBsaW5lLmNvbG9yID0gJ2dyZXk2MCcsIGxpbmUuc2l6ZSA9IDAuNCwgZmFjZXQuYnkgPSAnVGltZScsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ3Vuc2F0dXJhdGVkIGZhdHR5IGFjaWRzIGZlY2FsIGFuZCBpbnRha2UnKSArIHlsYWIoJ0NvbmNlbnRyYXRpb24nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcz0iZnJlZSIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wuU1QsIHg9J3Vuc2F0JywgeT0ndW5zYXQuaScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdVbnNhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBmZWNhbCBbbm1vbC9nXScsIHlsYWIgPSAnVW5zYXR1cmF0ZWQgZmF0dHkgYWNpZHMgY29uY2VudHJhdGlvbnMgaW50YWtlIFtnXScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzPSJmcmVlIikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKZ2dzY2F0dGVyKEZBX3N0b29sLlNULCB4PSd1bnNhdCcsIHk9J3Vuc2F0LmknLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1Vuc2F0dXJhdGVkIGZhdHR5IGFjaWRzIGNvbmNlbnRyYXRpb25zIGZlY2FsIFtubW9sL2ddJywgeWxhYiA9ICdVbnNhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBpbnRha2UgW2ddJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmBgYAoKS29ycmVsYXRpb25lbiBkdXJjaCBkaWUgTmFocnVuZyBhdWZnZW5vbW1lbmUgZ2Vzw6R0dGlndGUgRkEgbWl0IGbDpGthbGVuIGdlc8OkdHRpZ3RlbiBGQQoKYGBge3J9CnN0b29sLm1lbHQuc2F0IDwtIG1lbHQoRkFfc3Rvb2wuU1QsIGlkLnZhcnMgPSBjKCdUaW1lJywnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdzYXQnLCAnc2F0LmknKSkKCnN0b29sLm1lbHQuc2F0PC0gZHBseXI6OnJlbmFtZShzdG9vbC5tZWx0LnNhdCwgRkE9dmFyaWFibGUpCnN0b29sLm1lbHQuc2F0PC0gZHBseXI6OnJlbmFtZShzdG9vbC5tZWx0LnNhdCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCnN0b29sLm1lbHQuc2F0JFRpbWUgPC0gZmFjdG9yKHN0b29sLm1lbHQuc2F0JFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIikpCgoKZ2dwYWlyZWQoc3Rvb2wubWVsdC5zYXQsIHg9J0ZBJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBmYWNldC5ieSA9ICdUaW1lJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFKSArCiAgeGxhYignc2F0dXJhdGVkIGZhdHR5IGFjaWRzIGZlY2FsIGFuZCBpbnRha2UnKSArIHlsYWIoJ0NvbmNlbnRyYXRpb24nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcz0iZnJlZSIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wuU1QsIHg9J3NhdCcsIHk9J3NhdC5pJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1NhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBmZWNhbCBbbm1vbC9nXScsIHlsYWIgPSAnU2F0dXJhdGVkIGZhdHR5IGFjaWRzIGNvbmNlbnRyYXRpb25zIGludGFrZSBbZ10nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcz0iZnJlZSIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCmdnc2NhdHRlcihGQV9zdG9vbC5TVCwgeD0nc2F0JywgeT0nc2F0LmknLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1NhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBmZWNhbCBbbm1vbC9nXScsIHlsYWIgPSAnU2F0dXJhdGVkIGZhdHR5IGFjaWRzIGNvbmNlbnRyYXRpb25zIGludGFrZSBbZ10nKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKYGBgCgpXaWxjb3hvbi1UZXN0IHp3aXNjaGVuIFPDpHR0aWd1bmdzdHlwZW4gdW5kIEZldHRzw6R1cmVhdWZuYWhtZSBkdXJjaCBOYWhydW5nCgpgYGB7cn0KcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUFJFIikpJHNhdC5pLCBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQUkUiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUE9TVCIpKSRzYXQuaSwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUE9TVCIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFRpbWUgPT0gIlBSRSIpKSR1bnNhdC5pLCBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQUkUiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUE9TVCIpKSR1bnNhdC5pLCBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQT1NUIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRkFMU0UpCgoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJzYXQiKSkkc2F0LmksIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9RikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkc2F0LmksIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJHNhdC5pLCBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID1UKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkkc2F0LmksIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnVuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZD0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJHVuc2F0LmksIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9RikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkdW5zYXQuaSwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQ9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkkdW5zYXQuaSwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9VCkKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnVuc2F0IikpJHVuc2F0LmksIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnVuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZD0gRikKCmBgYAoKUGxvdHRlbiBkZXIgVW50ZXJzY2hpZWRlIHp3aXNjaGVuIGRlbiBTw6R0dGlndW5nc3R5cGVuCgpgYGB7cn0KRkFfc3Rvb2wuU1QkVGltZSA8LSBmYWN0b3IoRkFfc3Rvb2wuU1QkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmdncGxvdChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNUKSksIGFlcyh4PVBoZW5vdHlwZSwgeT1zYXQuaSkpICsgeGxhYignUGhlbm90eXBlJykgKyB5bGFiKCdJbnRha2UgU2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbZ10nKSArCiAgZ2VvbV9ib3hwbG90KGZpbGw9J3doaXRlc21va2UnLCBjb2xvcj0nYmxhY2snKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjMsIGZpbGwgPSAnZ3JleTIyJywgY29sb3I9J2dyZXkyMicpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fc2F0KSArIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QpKSwgYWVzKHg9UGhlbm90eXBlLCB5PXVuc2F0LmkpKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignSW50YWtlIHVuc2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbZ10nKSArCiAgZ2VvbV9ib3hwbG90KGZpbGw9J3doaXRlc21va2UnLCBjb2xvcj0nYmxhY2snKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjMsIGZpbGwgPSAnZ3JleTIyJywgY29sb3I9J2dyZXkyMicpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fc2F0KSArIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QpKSwgYWVzKHg9VGltZSwgeT1zYXQuaSkpICsgeGxhYignVGltZSBQb2ludCcpICsgCiAgeWxhYignSW50YWtlIHNhdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW2ddJykgKyAKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvcj0gJ2dyZXkyMicpICsgCiAgZmFjZXRfd3JhcCh+UGhlbm90eXBlKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGLCBhZXMobGFiZWw9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QpKSwgYWVzKHg9VGltZSwgeT11bnNhdC5pKSkgKyB4bGFiKCdUaW1lIFBvaW50JykgKyAKICB5bGFiKCdJbnRha2UgdW5hdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW2ddJykgKyAKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvcj0gJ2dyZXkyMicpICsgCiAgZmFjZXRfd3JhcCh+UGhlbm90eXBlKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGLCBhZXMobGFiZWw9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKCmBgYAoKQmVzdGltbWVuIGRlciBIREwgdW5kIExETCBLb256ZW50cmF0aW9uZW4gdW5kIFJhdGlvIGRlciBTw6R0dGlndW5nc3R5cGVuCgpQbG90dGVuIHZvbiBLb3JyZWxhdGlvbiB6d2lzY2hlbiBMREwgdW5kIGbDpGthbGVuIGdlc8OkdHRpZ3RlbiBGQQoKYGBge3J9Cmdnc2NhdHRlcihGQV9zdG9vbC5TVCwgeD0nc2F0JywgeT0nTERMJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1NhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBmZWNhbCBbbm1vbC9nXScsIHlsYWIgPSAnTERMIENvbmNlbnRyYXRpb24gW21nL2RsXScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzPSJmcmVlIikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKZ2dzY2F0dGVyKEZBX3N0b29sLlNULCB4PSdzYXQnLCB5PSdMREwnLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1NhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBmZWNhbCBbbm1vbC9nXScsIHlsYWIgPSAnTERMIENvbmNlbnRyYXRpb24gW21nL2RsXScpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQpgYGAKClBsb3R0ZW4gdm9uIEtvcnJlbGF0aW9uZW4gendpc2NoZW4gSERMIHVuZCBmw6RrYWxlbiBnZXPDpHR0aWd0ZW4gRkEKCmBgYHtyfQpnZ3NjYXR0ZXIoRkFfc3Rvb2wuU1QsIHg9J3NhdCcsIHk9J0hETCcsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZHMgY29uY2VudHJhdGlvbnMgZmVjYWwgW25tb2wvZ10nLCB5bGFiID0gJ0hETCBDb25jZW50cmF0aW9uIFttZy9kbF0nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcz0iZnJlZSIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCmdnc2NhdHRlcihGQV9zdG9vbC5TVCwgeD0nc2F0JywgeT0nSERMJywgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZHMgY29uY2VudHJhdGlvbnMgZmVjYWwgW25tb2wvZ10nLCB5bGFiID0gJ0hETCBDb25jZW50cmF0aW9uIFttZy9kbF0nKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKYGBgCgpQbG90dGVuIHZvbiBLb3JyZWxhdGlvbmVuIHp3aXNjaGVuIEhETC9MREwtcmF0aW8gdW5kIGbDpGthbGVuIGdlc8OkdHRpZ3RlbiBGQQoKYGBge3J9Cmdnc2NhdHRlcihGQV9zdG9vbC5TVCwgeD0nc2F0JywgeT0nTERMX0hETF9yYXRpbycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZHMgY29uY2VudHJhdGlvbnMgZmVjYWwgW25tb2wvZ10nLCB5bGFiID0gJ0xETC9IREwgcmF0aW8nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcz0iZnJlZSIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCmdnc2NhdHRlcihGQV9zdG9vbC5TVCwgeD0nc2F0JywgeT0nTERMX0hETF9yYXRpbycsIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU2F0dXJhdGVkIGZhdHR5IGFjaWRzIGNvbmNlbnRyYXRpb25zIGZlY2FsIFtubW9sL2ddJywgeWxhYiA9ICdMREwvSERMIHJhdGlvJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmBgYAoKUGxvdHRlbiB2b24gS29ycmVsYXRpb25lbiB6d2lzY2hlbiBMREwgdW5kIGbDpGthbGVuIHVuZ2Vzw6R0dGlndGVuIEZBCgpgYGB7cn0KZ2dzY2F0dGVyKEZBX3N0b29sLlNULCB4PSd1bnNhdCcsIHk9J0xETCcsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdVbnNhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBmZWNhbCBbbm1vbC9nXScsIHlsYWIgPSAnTERMIENvbmNlbnRyYXRpb24gW21nL2RsXScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzPSJmcmVlIikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKZ2dzY2F0dGVyKEZBX3N0b29sLlNULCB4PSd1bnNhdCcsIHk9J0xETCcsIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnVW5zYXR1cmF0ZWQgZmF0dHkgYWNpZHMgY29uY2VudHJhdGlvbnMgZmVjYWwgW25tb2wvZ10nLCB5bGFiID0gJ0xETCBDb25jZW50cmF0aW9uIFttZy9kbF0nKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKYGBgCgpQbG90dGVuIHZvbiBLb3JyZWxhdGlvbmVuIHp3aXNjaGVuIEhETCB1bmQgZsOka2FsZW4gdW5nZXPDpHR0aWd0ZW4gRkEKCmBgYHtyfQpnZ3NjYXR0ZXIoRkFfc3Rvb2wuU1QsIHg9J3Vuc2F0JywgeT0nSERMJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1Vuc2F0dXJhdGVkIGZhdHR5IGFjaWRzIGNvbmNlbnRyYXRpb25zIGZlY2FsIFtubW9sL2ddJywgeWxhYiA9ICdIREwgQ29uY2VudHJhdGlvbiBbbWcvZGxdJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXM9ImZyZWUiKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wuU1QsIHg9J3Vuc2F0JywgeT0nSERMJywgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdVbnNhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBmZWNhbCBbbm1vbC9nXScsIHlsYWIgPSAnSERMIENvbmNlbnRyYXRpb24gW21nL2RsXScpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQpgYGAKClBsb3R0ZW4gdm9uIEtvcnJlbGF0aW9uZW4gendpc2NoZW4gSERML0xETC1yYXRpbyB1bmQgZsOka2FsZW4gdW5nZXPDpHR0aWd0ZW4gRkEKCmBgYHtyfQpnZ3NjYXR0ZXIoRkFfc3Rvb2wuU1QsIHg9J3Vuc2F0JywgeT0nTERMX0hETF9yYXRpbycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdVbnNhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBmZWNhbCBbbm1vbC9nXScsIHlsYWIgPSAnTERML0hETCByYXRpbycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzPSJmcmVlIikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKZ2dzY2F0dGVyKEZBX3N0b29sLlNULCB4PSd1bnNhdCcsIHk9J0xETF9IRExfcmF0aW8nLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1Vuc2F0dXJhdGVkIGZhdHR5IGFjaWRzIGNvbmNlbnRyYXRpb25zIGZlY2FsIFtubW9sL2ddJywgeWxhYiA9ICdMREwvSERMIHJhdGlvJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmBgYAoKUGxvdHRlbiB2b24gS29ycmVsYXRpb25lbiB6d2lzY2hlbiBMREwgdW5kIGF1Zmdlbm9tbWVuZW4gZ2Vzw6R0dGlndGVuIEZBCgpgYGB7cn0KZ2dzY2F0dGVyKEZBX3N0b29sLlNULCB4PSdzYXQuaScsIHk9J0xETCcsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZHMgY29uY2VudHJhdGlvbnMgaW50YWtlIFtnXScsIHlsYWIgPSAnTERMIENvbmNlbnRyYXRpb24gW21nL2RsXScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzPSJmcmVlIikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKZ2dzY2F0dGVyKEZBX3N0b29sLlNULCB4PSdzYXQuaScsIHk9J0xETCcsIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU2F0dXJhdGVkIGZhdHR5IGFjaWRzIGNvbmNlbnRyYXRpb25zIGludGFrZSBbZ10nLCB5bGFiID0gJ0xETCBDb25jZW50cmF0aW9uIFttZy9kbF0nKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKYGBgCgpQbG90dGVuIHZvbiBLb3JyZWxhdGlvbmVuIHp3aXNjaGVuIEhETCB1bmQgYXVmZ2Vub21tZW5lbiBnZXPDpHR0aWd0ZW4gRkEKCmBgYHtyfQpnZ3NjYXR0ZXIoRkFfc3Rvb2wuU1QsIHg9J3NhdC5pJywgeT0nSERMJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1NhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBpbnRha2UgW2ddJywgeWxhYiA9ICdIREwgQ29uY2VudHJhdGlvbiBbbWcvZGxdJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXM9ImZyZWUiKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wuU1QsIHg9J3NhdC5pJywgeT0nSERMJywgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZHMgY29uY2VudHJhdGlvbnMgaW50YWtlIFtnXScsIHlsYWIgPSAnSERMIENvbmNlbnRyYXRpb24gW21nL2RsXScpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQpgYGAKClBsb3R0ZW4gdm9uIEtvcnJlbGF0aW9uZW4gendpc2NoZW4gTERML0hETC1yYXRpbyB1bmQgYXVmZ2Vub21tZW5lbiBnZXPDpHR0aWd0ZW4gRkEKCmBgYHtyfQpnZ3NjYXR0ZXIoRkFfc3Rvb2wuU1QsIHg9J3NhdC5pJywgeT0nTERMX0hETF9yYXRpbycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTYXR1cmF0ZWQgZmF0dHkgYWNpZHMgY29uY2VudHJhdGlvbnMgaW50YWtlIFtnXScsIHlsYWIgPSAnTERML0hETCByYXRpbycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzPSJmcmVlIikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKZ2dzY2F0dGVyKEZBX3N0b29sLlNULCB4PSdzYXQuaScsIHk9J0xETF9IRExfcmF0aW8nLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1NhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBpbnRha2UgW2ddJywgeWxhYiA9ICdMREwvSERMIHJhdGlvJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmBgYAoKUGxvdHRlbiB2b24gS29ycmVsYXRpb25lbiB6d2lzY2hlbiBMREwgdW5kIGF1Zmdlbm9tbWVuZW4gdW5nZXPDpHR0aWd0ZW4gRkEKYGBge3J9Cmdnc2NhdHRlcihGQV9zdG9vbC5TVCwgeD0ndW5zYXQuaScsIHk9J0xETCcsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdVbnNhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBpbnRha2UgW2ddJywgeWxhYiA9ICdMREwgQ29uY2VudHJhdGlvbiBbbWcvZGxdJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXM9ImZyZWUiKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wuU1QsIHg9J3Vuc2F0LmknLCB5PSdMREwnLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1Vuc2F0dXJhdGVkIGZhdHR5IGFjaWRzIGNvbmNlbnRyYXRpb25zIGludGFrZSBbZ10nLCB5bGFiID0gJ0xETCBDb25jZW50cmF0aW9uIFttZy9kbF0nKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKYGBgCgpQbG90dGVuIHZvbiBLb3JyZWxhdGlvbmVuIHp3aXNjaGVuIEhETCB1bmQgYXVmZ2Vub21tZW5lbiB1bmdlc8OkdHRpZ3RlbiBGQQoKYGBge3J9Cmdnc2NhdHRlcihGQV9zdG9vbC5TVCwgeD0ndW5zYXQuaScsIHk9J0hETCcsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdVbnNhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBpbnRha2UgW2ddJywgeWxhYiA9ICdIREwgQ29uY2VudHJhdGlvbiBbbWcvZGxdJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXM9ImZyZWUiKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wuU1QsIHg9J3Vuc2F0LmknLCB5PSdIREwnLCBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1Vuc2F0dXJhdGVkIGZhdHR5IGFjaWRzIGNvbmNlbnRyYXRpb25zIGludGFrZSBbZ10nLCB5bGFiID0gJ0hETCBDb25jZW50cmF0aW9uIFttZy9kbF0nKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKYGBgCgpQbG90dGVuIHZvbiBLb3JyZWxhdGlvbmVuIHp3aXNjaGVuIExETC9IREwtcmF0aW8gdW5kIGF1Zmdlbm9tbWVuZW4gdW5nZXPDpHR0aWd0ZW4gRkEKCgpgYGB7cn0KZ2dzY2F0dGVyKEZBX3N0b29sLlNULCB4PSd1bnNhdC5pJywgeT0nTERMX0hETF9yYXRpbycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdVbnNhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBpbnRha2UgW2ddJywgeWxhYiA9ICdMREwvSERMIHJhdGlvJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXM9ImZyZWUiKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpnZ3NjYXR0ZXIoRkFfc3Rvb2wuU1QsIHg9J3Vuc2F0LmknLCB5PSdMRExfSERMX3JhdGlvJywgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdVbnNhdHVyYXRlZCBmYXR0eSBhY2lkcyBjb25jZW50cmF0aW9ucyBpbnRha2UgW2ddJywgeWxhYiA9ICdMREwvSERMIHJhdGlvJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmBgYAoKV2lsY294b24tVGVzdCBVbnRlcnNjaGllZGUgaW4gTERMIHVuZCBIREwtS29uemVudHJhdGlvbmVuIHp3aXNjaGVuIGRlbiBTw6R0dGlndW5nc3R5cGVuCgpgYGB7cn0KcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUFJFIikpJExETCwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFRpbWUgPT0gIlBPU1QiKSkkTERMLCBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQT1NUIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRkFMU0UpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQUkUiKSkkSERMLCBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQUkUiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUE9TVCIpKSRIREwsIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFRpbWUgPT0gIlBPU1QiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGQUxTRSkKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJExETCwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJzYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID1GKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRMREwsIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJExETCwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9VCkKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnVuc2F0IikpJExETCwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJzYXQiKSkkSERMLCBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBQaGVub3R5cGUgPT0gInNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPUYpCiAKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRIREwsIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJEhETCwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9VCkKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnVuc2F0IikpJEhETCwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkPSBGKQoKCmBgYAoKUGxvdHRlbiBkZXIgVW50ZXJzY2hpZWRlCgpgYGB7cn0KRkFfc3Rvb2wuU1QkVGltZSA8LSBmYWN0b3IoRkFfc3Rvb2wuU1QkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmdncGxvdChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNUKSksIGFlcyh4PVBoZW5vdHlwZSwgeT1MREwpKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignTERMIGNvbmNlbnRyYXRpb24gW21nL2RsXScpICsKICBnZW9tX2JveHBsb3QoZmlsbD0nd2hpdGVzbW9rZScsIGNvbG9yPSdibGFjaycpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXM9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMywgZmlsbCA9ICdncmV5MjInLCBjb2xvcj0nZ3JleTIyJykgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl9zYXQpICsgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCkpLCBhZXMoeD1QaGVub3R5cGUsIHk9SERMKSkgKyB4bGFiKCdQaGVub3R5cGUnKSArIHlsYWIoJ0hETCBjb25jZW50cmF0aW9uIFttZy9kbF0nKSArCiAgZ2VvbV9ib3hwbG90KGZpbGw9J3doaXRlc21va2UnLCBjb2xvcj0nYmxhY2snKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjMsIGZpbGwgPSAnZ3JleTIyJywgY29sb3I9J2dyZXkyMicpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fc2F0KSArIGZhY2V0X3dyYXAoflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QpKSwgYWVzKHg9UGhlbm90eXBlLCB5PUxETF9IRExfcmF0aW8pKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignTERML0hETCByYXRpbycpICsKICBnZW9tX2JveHBsb3QoZmlsbD0nd2hpdGVzbW9rZScsIGNvbG9yPSdibGFjaycpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXM9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMywgZmlsbCA9ICdncmV5MjInLCBjb2xvcj0nZ3JleTIyJykgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl9zYXQpICsgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCkpLCBhZXMoeD1UaW1lLCB5PUxETCkpICsgeGxhYignVGltZSBQb2ludCcpICsgCiAgeWxhYignTERMIGNvbmNlbnRyYXRpb24gW21nL2RsXScpICsgCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3I9ICdncmV5MjInKSArIAogIGZhY2V0X3dyYXAoflBoZW5vdHlwZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRiwgYWVzKGxhYmVsPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fdGltZSkKCmdncGxvdChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNUKSksIGFlcyh4PVRpbWUsIHk9SERMKSkgKyB4bGFiKCdUaW1lIFBvaW50JykgKyAKICB5bGFiKCdIREwgY29uY2VudHJhdGlvbiBbbWcvZGxdJykgKyAKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvcj0gJ2dyZXkyMicpICsgCiAgZmFjZXRfd3JhcCh+UGhlbm90eXBlKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGLCBhZXMobGFiZWw9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKCmdncGxvdChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNUKSksIGFlcyh4PVRpbWUsIHk9TERMX0hETF9yYXRpbykpICsgeGxhYignVGltZSBQb2ludCcpICsgCiAgeWxhYignTERML0hETCByYXRpbycpICsgCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3I9ICdncmV5MjInKSArIAogIGZhY2V0X3dyYXAoflBoZW5vdHlwZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRiwgYWVzKGxhYmVsPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fdGltZSkKCmBgYAoKVGVzdGVuIGRlciBzaWduaWZpa2FudGVuIFVudGVyc2NoaWVkZSBkZXIgRmV0dHPDpHVyZW5hdXNzY2hlaWR1bmcgZGVyIFPDpHR0aWd1bmdzdHlwZW4KTGFkZW4gdW5kIGZpbHRlcm4gZGVyIE1ldGFkYXRlbgoKYGBge3J9CkZBX3N0b29sLlNUIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIHNhdHVyYXRpb24gbWl0IGludGFrZSB0eXBlcy50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLAogICAgICAgICAgICAgICAgICAgICAgIGhlYWQ9VCkKClZpZXcoRkFfc3Rvb2wpCgpGQV9zdG9vbC5TVCRUaW1lIDwtZmFjdG9yKEZBX3N0b29sLlNUJFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIikpCgpyb3cubmFtZXMoRkFfc3Rvb2wuU1QpIDwtIEZBX3N0b29sLlNUJFNhbXBsZUlECgpGQV9zdG9vbC5TVCRQcm9iYW5kCgpGQV9zdG9vbC5TVCA8LSBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCAhU2FtcGxlSUQgPT0gIlNULjM1QUQuMFUxIikpCgpGQV9zdG9vbC5TVCA8LSBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCAhUHJvYmFuZCA9PSAiMzNNUCIsICFQcm9iYW5kID09ICIzNUFEIiwgIVByb2JhbmQgPT0gIjM0V0YiLCAhUHJvYmFuZCA9PSAiNDlSSiIpKQoKY29tcGFyaXNvbl9zYXQgPC0gbGlzdChjKCJzYXQiLCAidW5zYXQiKSkKCmNvbXBhcmlzb25fY2hhbmdlIDwtIGxpc3QoYygiY2hhbmdlLnNhdCIsICJjaGFuZ2UudW5zYXQiKSkKCmNvbXBhcmlzb25fdGltZSA8LSBsaXN0KGMoIlBSRSIsICJQT1NUIikpCmBgYAoKCldpbGNveG9uIFRlc3QgVW50ZXJzY2hpZWRlIGbDpGthbGVyIEZldHRzw6R1cmVrb256ZW50cmF0aW9uZW4gendpc2NoZW4gU8OkdHRpZ3VuZ3N0eXBlbgoKYGBge3J9CnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFRpbWUgPT0gIlBSRSIpKSRzYXQsIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFRpbWUgPT0gIlBSRSIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQT1NUIikpJHNhdCwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUE9TVCIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUFJFIikpJHVuc2F0LCBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQUkUiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUE9TVCIpKSR1bnNhdCwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUE9TVCIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJzYXQiKSkkc2F0LCBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBQaGVub3R5cGUgPT0gInNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPUYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBQaGVub3R5cGUgPT0gInVuc2F0IikpJHNhdCwgc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQ9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkkc2F0LCBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID1UKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkkc2F0LCBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQ9IEYpCgpgYGAKClBsb3R0ZW4gZGVyIFVudGVyc2NoaWVkZQoKYGBge3J9CmdncGxvdChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNUKSksIGFlcyh4PVBoZW5vdHlwZSwgeT1zYXQpKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignU2F0dXJhdGVkIGZhdHR5IGFjaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9nIERXXScpICsKICBnZW9tX2JveHBsb3QoZmlsbD0nd2hpdGVzbW9rZScsIGNvbG9yPSdibGFjaycpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXM9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMywgZmlsbCA9ICdncmV5MjInLCBjb2xvcj0nZ3JleTIyJykgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl9zYXQpICsgZmFjZXRfd3JhcCh+VGltZSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCkpLCBhZXMoeD1QaGVub3R5cGUsIHk9dW5zYXQpKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignVW5zYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKwogIGdlb21fYm94cGxvdChmaWxsPSd3aGl0ZXNtb2tlJywgY29sb3I9J2JsYWNrJykgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcz0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4zLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yPSdncmV5MjInKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSwgYWVzKGxhYmVsID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3NhdCkgKyBmYWNldF93cmFwKH5UaW1lKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNUKSksIGFlcyh4PVRpbWUsIHk9c2F0KSkgKyB4bGFiKCdUaW1lIFBvaW50JykgKyAKICB5bGFiKCdTYXR1cmF0ZWQgZmF0dHkgYWNpZCBDb25jZW50cmF0aW9uIFtubW9sL2cgRFddJykgKyAKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvcj0gJ2dyZXkyMicpICsgCiAgZmFjZXRfd3JhcCh+UGhlbm90eXBlKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGLCBhZXMobGFiZWw9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QpKSwgYWVzKHg9VGltZSwgeT11bnNhdCkpICsgeGxhYignVGltZSBQb2ludCcpICsgCiAgeWxhYignVW5hdHVyYXRlZCBmYXR0eSBhY2lkIENvbmNlbnRyYXRpb24gW25tb2wvZyBEV10nKSArIAogIGdlb21fYm94cGxvdChmaWxsID0gJ3doaXRlc21va2UnLCBjb2xvcj0iYmxhY2siKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yPSAnZ3JleTIyJykgKyAKICBmYWNldF93cmFwKH5QaGVub3R5cGUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEYsIGFlcyhsYWJlbD0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3RpbWUpCmBgYAoKQmVzdGltbWVuIGRlciBtZWFucyB1bmQgU0QKCmBgYHtyfQptZWFuKHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gInNhdCIpKSRzYXQpIAoKc2Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAic2F0IikpJHNhdCkgCgptZWFuKHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJzYXQiKSkkc2F0KSAKCiBzZChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAic2F0IikpJHNhdCkKIAoKbWVhbihzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRzYXQpCgpzZChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRzYXQpCgptZWFuKHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRzYXQpCgpzZChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkc2F0KQoKbWVhbihzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJzYXQiKSkkdW5zYXQpCgpzZChzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJzYXQiKSkkdW5zYXQpCgptZWFuKHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJzYXQiKSkkdW5zYXQpIAoKc2Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gInNhdCIpKSR1bnNhdCkgCgoKCm1lYW4oc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkdW5zYXQpIAoKc2Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkdW5zYXQpIAoKbWVhbihzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkdW5zYXQpIAoKc2Qoc3Vic2V0KGZpbHRlcihGQV9zdG9vbC5TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gInVuc2F0IikpJHVuc2F0KQpgYGAKClRlc3RlbiB2b24gVW50ZXJzY2hpZWRlIGltIHJlbGF0aXZlbiBWb3Jrb21tZW4gZGVyIFRheGEgendpc2NoZW4gZGVuIFPDpHR0aWd1bmdzdHlwZW4KTGFkZW4gZGVyIFBoeWx1bS1NZXRhZGF0ZW4gcy5vLgpTeW5jaHJvbmlzaWVyZW4gZGVyIERhdGVuLCBoaW56dWbDvGdlbiB2b24gbG9nLVRyYW5zZm9ybWF0aW9uIHVuZCBQc2V1ZG9jb3VudCAwLjAwMDAxCgpgYGB7cn0KcmVsYWJfcGh5bHVtX0lEIDwtIHJlbGFiX3BoeWx1bV9zcHJlYWQKCnJlbGFiX3BoeWx1bV9JRCA8LSBtdXRhdGUocmVsYWJfcGh5bHVtX0lELCBTYW1wbGVJRCA9IHBhc3RlKFByb2JhbmQsIFRpbWUsc2VwPSIuIikpCgpyb3cubmFtZXMocmVsYWJfcGh5bHVtX0lEKSA8LSByZWxhYl9waHlsdW1fSUQkU2FtcGxlSUQKCnJlbGFiX2dlbnVzX0lEIDwtIHJlbGFiX2dlbnVzX3NwcmVhZAoKcmVsYWJfZ2VudXNfSUQgPC0gbXV0YXRlKHJlbGFiX2dlbnVzX0lELCBTYW1wbGVJRCA9IHBhc3RlKFByb2JhbmQsIFRpbWUsIHNlcCA9Ii4iKSkKCnJvdy5uYW1lcyhyZWxhYl9nZW51c19JRCkgPC0gcmVsYWJfZ2VudXNfSUQkU2FtcGxlSUQKCgpGQV9zdG9vbCA8LSBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLCAhUHJvYmFuZCA9PSAiMzFLRSIsICFQcm9iYW5kID09ICIzNFdGIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAhUHJvYmFuZCA9PSAiNDVHTCIsICFQcm9iYW5kID09ICI0OVJKIiwgIVByb2JhbmQgPT0gIjU0U0wiLCAhUHJvYmFuZCA9PSAiNzRTQSIpKQoKRkFfc3Rvb2wuU1QgPC0gbXV0YXRlKEZBX3N0b29sLlNULCBTYW1wbGVJRDEgPSBwYXN0ZShQcm9iYW5kLCBUaW1lLCBzZXAgPSAiLiIpKQoKcm93Lm5hbWVzKEZBX3N0b29sLlNUKSA8LSBGQV9zdG9vbC5TVCRTYW1wbGVJRDEKCmNvbW1vbi5pZHMucmVsYWIgPC0gaW50ZXJzZWN0KHJvd25hbWVzKEZBX3N0b29sLlNUKSwgcm93bmFtZXMocmVsYWJfcGh5bHVtX0lEKSkKCkZBX3N0b29sLlNUIDwtIEZBX3N0b29sLlNUW2NvbW1vbi5pZHMucmVsYWIsXQoKcmVsYWJfcGh5bHVtX0lEIDwtIHJlbGFiX3BoeWx1bV9JRFtjb21tb24uaWRzLnJlbGFiLF0KCnJlbGFiX2dlbnVzX0lEIDwtIHJlbGFiX2dlbnVzX0lEW2NvbW1vbi5pZHMucmVsYWIsXQoKcmVsYWJfcGh5bHVtX0lEMSA8LSByZWxhYl9waHlsdW1fSURbLGMoMzo4KV0gKyAwLjAwMDAxCgpyZWxhYl9waHlsdW1fSURfbG9nIDwtIGxvZzEwKHJlbGFiX3BoeWx1bV9JRF9sb2cpCgoKcGh5bHVtX1NUIDwtIGNiaW5kKHJlbGFiX3BoeWx1bV9JRDEsIEZBX3N0b29sLlNUKQoKd3JpdGUudGFibGUocGh5bHVtX1NULCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL0ZBIGZlY2FsL3NhdHVyYXRpb24gdHlwZXMvcGh5bHVtLXBoZW5vdHlwZS50eHQnLCBzZXAgPSAiXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCldpbGNveG9uLVRlc3QgenVyIEJlc3RpbW11bmcgdm9uIFVudGVyc2NoaWVkZSBpbSByZWxhdGl2ZW4gVm9ya29tbWVuIGRlciBQaHlsYSB6d2lzY2hlbiBTw6R0dGlndW5nc3R5cGVuCgpGaXJtaWN1dGVzCgpgYGB7cn0KcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIikpJGtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMsIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJzYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnNhdCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcywgc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnVuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJzYXQiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcywgc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKCmdncGxvdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCkpLCBhZXMoeD1QaGVub3R5cGUseT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzKSkgKyB4bGFiKCdQaGVub3R5cGUnKSArIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fRmlybWljdXRlcyknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fc2F0KQoKZ2dwbG90KHN1YnNldChmaWx0ZXIocGh5bHVtX1NUKSksIGFlcyh4PVRpbWUseT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzKSkgKyB4bGFiKCdUaW1lJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0Zpcm1pY3V0ZXMpJykgKwogIGdlb21fYm94cGxvdChmaWxsID0gJ3doaXRlc21va2UnLCBjb2xvcj0iYmxhY2siKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yID0gJ2dyZXkyMicpICsKICBmYWNldF93cmFwKH5QaGVub3R5cGUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fdGltZSkKCgpgYGAKCkFjdGlub2JhY3RlcmlhCgpgYGB7cn0KCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiKSkka19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEsIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGQUxTRSkKIApwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIpKSRrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYSwgc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBPU1QiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGQUxTRSkKCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QpKSwgYWVzKHg9UGhlbm90eXBlLHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEpKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fc2F0KSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QpKSwgYWVzKHg9VGltZSx5PWtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhKSkgKyB4bGFiKCdUaW1lJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvciA9ICdncmV5MjInKSArCiAgZmFjZXRfd3JhcCh+UGhlbm90eXBlKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSwgYWVzKGxhYmVsID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3RpbWUpCnBoeWx1bV9TVCRrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYQoKYGBgCgpCYWN0ZXJvaWRldGVzCkluIEFyYmVpdAoKYGBge3J9CgptZWFuKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJzYXQiKSkka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcykgCgpzZChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAic2F0IikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMpIAoKbWVhbihzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gInNhdCIpKSRrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzKSAKCnNkKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAic2F0IikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMpIAoKCm1lYW4oc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcykgCgpzZChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnNhdCIpKSRrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzKQoKbWVhbihzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcykgCgpzZChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcykgCgoKCm1lYW4oc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gInVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMpIAoKc2Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gInVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMpIAoKbWVhbihzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gInVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMpIAoKc2Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzKQoKCm1lYW4oc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzKSAKCnNkKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcykgCgptZWFuKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMpIAoKc2Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcykKCgoKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiKSkka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcywgc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBPU1QiKSkka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcywgc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBPU1QiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGQUxTRSkKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJzYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gInVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMsIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gInVuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMsIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCmxpYnJhcnkoc2NhbGVzKQoKcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL3NhdC50eXBlcy5iYWN0ZXJvaWRldGVzLm5ldS5wZGYiLHdpZHRoPTgsIGhlaWdodD0xMCkKZ2dwbG90KHN1YnNldChmaWx0ZXIocGh5bHVtX1NUKSksIGFlcyh4PVBoZW5vdHlwZSx5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMsIGZpbGw9IFBoZW5vdHlwZSkpICsgCiAgeGxhYignUGhlbm90eXBlJykgKyB5bGFiKCdSZWxhdGl2ZXMgVm9ya29tbWVuIHBfX0JhY3Rlcm9pZGV0ZXMgWyVdJykgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IC43LCBsd2Q9MC42KSArIHRoZW1lX2NsYXNzaWMoKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJjaGFuZ2Uuc2F0IiA9ICJ6dSBnZXPDpHR0aWd0IiwgImNoYW5nZS51bnNhdCIgPSAienUgdW5nZXPDpHR0aWd0IiwgInNhdCIgPSAiZ2Vzw6R0dGlndCIsICJ1bnNhdCI9ICJ1bmdlc8OkdHRpZ3QiKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygid2VjaHNlbCB6dSBnZXPDpHR0aWd0IiwgIndlY2hzZWwgenUgdW5nZXPDpHR0aWd0IiwgImdlc8OkdHRpZ3QiLCAidW5nZXPDpHR0aWd0IiksCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygibGlnaHRza3libHVlNCIsICJsaWdodHNreWJsdWUzIiwgImxpZ2h0c2t5Ymx1ZTIiLCAibGlnaHRza3libHVlIikpKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fc2F0KSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCBoanVzdD0xKSkrCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKQpkZXYub2ZmKCkKCmdncGxvdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCkpLCBhZXMoeD1UaW1lLHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcykpICsgeGxhYignVGltZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvciA9ICdncmV5MjInKSArCiAgZmFjZXRfd3JhcCh+UGhlbm90eXBlKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSwgYWVzKGxhYmVsID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3RpbWUpCgoKYGBgCgpQcm90ZW9iYWN0ZXJpYQoKYGBge3J9CnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiKSkka19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEsIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGQUxTRSkKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIikpJGtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKCmdncGxvdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCkpLCBhZXMoeD1QaGVub3R5cGUseT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYSkpICsgeGxhYignUGhlbm90eXBlJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvciA9ICdncmV5MjInKSArCiAgZmFjZXRfd3JhcCh+VGltZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl9zYXQpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QpKSwgYWVzKHg9VGltZSx5PWtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhKSkgKyB4bGFiKCdUaW1lJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvciA9ICdncmV5MjInKSArCiAgZmFjZXRfd3JhcCh+UGhlbm90eXBlKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSwgYWVzKGxhYmVsID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3RpbWUpCgpgYGAKCgpUZW5lcmljdXRlcwoKYGBge3J9CgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUFJFIikpJGtfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRkFMU0UpCiAKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBPU1QiKSkka19fQmFjdGVyaWEucF9fVGVuZXJpY3V0ZXMsIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRkFMU0UpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QpKSwgYWVzKHg9UGhlbm90eXBlLHk9a19fQmFjdGVyaWEucF9fVGVuZXJpY3V0ZXMpKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcyknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fc2F0KQoKZ2dwbG90KHN1YnNldChmaWx0ZXIocGh5bHVtX1NUKSksIGFlcyh4PVRpbWUseT1rX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcykpICsgeGxhYignVGltZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcyknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflBoZW5vdHlwZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKYGBgCgpWZXJydWNvbWljcm9iaWEKSW4gQXJiZWl0CgpgYGB7cn0KCm1lYW4oc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gInNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEpIAoKc2Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gInNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEpIAoKbWVhbihzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gInNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEpIAoKc2Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJzYXQiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhKSAKCgptZWFuKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSkgCgpzZChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEpIAoKbWVhbihzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhKSAKCnNkKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEpIAoKCgptZWFuKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEpIAoKc2Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gInVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSkgCgptZWFuKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhKSAKCnNkKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhKQoKCm1lYW4oc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEpIAoKc2Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEpIAoKbWVhbihzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEpCgpzZChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEpCgoKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRkFMU0UpCiAKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBPU1QiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSwgc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEsIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gInVuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSwgc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIocGh5bHVtX1NUKSksIGFlcyh4PVBoZW5vdHlwZSx5PTEwXmtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYSkpICsgeGxhYignUGhlbm90eXBlJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fc2F0KSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIocGh5bHVtX1NUKSksIGFlcyh4PVBoZW5vdHlwZSx5PTEwXmtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMpKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvciA9ICdncmV5MjInKSArCiAgZmFjZXRfd3JhcCh+VGltZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl9zYXQpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSArCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKQoKCmdncGxvdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCkpLCBhZXMoeD1UaW1lLHk9a19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhKSkgKyB4bGFiKCdUaW1lJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflBoZW5vdHlwZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL3NhdC50eXBlcy52ZXJydWNvbWljcm9iaWEubmV1LnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QpKSwgYWVzKHg9UGhlbm90eXBlLHk9a19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLCBmaWxsPSBQaGVub3R5cGUpKSArIAogIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignUmVsYXRpdmVzIFZvcmtvbW1lbiBwX19WZXJydWNvbWljcm9iaWEgWyVdJykgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IC43LCBsd2Q9MC42KSArIHRoZW1lX2NsYXNzaWMoKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJjaGFuZ2Uuc2F0IiA9ICJ6dSBnZXPDpHR0aWd0IiwgImNoYW5nZS51bnNhdCIgPSAienUgdW5nZXPDpHR0aWd0IiwgInNhdCIgPSAiZ2Vzw6R0dGlndCIsICJ1bnNhdCI9ICJ1bmdlc8OkdHRpZ3QiKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygid2VjaHNlbCB6dSBnZXPDpHR0aWd0IiwgIndlY2hzZWwgenUgdW5nZXPDpHR0aWd0IiwgImdlc8OkdHRpZ3QiLCAidW5nZXPDpHR0aWd0IiksCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygibGlnaHRza3libHVlNCIsICJsaWdodHNreWJsdWUzIiwgImxpZ2h0c2t5Ymx1ZTIiLCAibGlnaHRza3libHVlIikpKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9ICkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT00NSwgaGp1c3Q9MSkpKwogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoKSkKZGV2Lm9mZigpCgpgYGAKCkxhZGVuIGRlciBHZW51cy1NZXRhZGF0ZW4gcy5vLgpTeW5jaHJvbmlzaWVyZW4gZGVyIERhdGVuLCBoaW56dWbDvGdlbiB2b24gbG9nLVRyYW5zZm9ybWF0aW9uIHVuZCBQc2V1ZG9jb3VudCAwLjAwMDAxCgpgYGB7cn0KY29tbW9uLmlkcy5yZWxhYiA8LSBpbnRlcnNlY3Qocm93bmFtZXMoRkFfc3Rvb2wuU1QpLCByb3duYW1lcyhyZWxhYl9nZW51c19JRCkpCgpGQV9zdG9vbC5TVCA8LSBGQV9zdG9vbC5TVFtjb21tb24uaWRzLnJlbGFiLF0KCnJlbGFiX2dlbnVzX0lEIDwtIHJlbGFiX2dlbnVzX0lEW2NvbW1vbi5pZHMucmVsYWIsXQoKcmVsYWJfZ2VudXNfSUQgPC0gcmVsYWJfZ2VudXNfSURbY29tbW9uLmlkcy5yZWxhYixdCgpyZWxhYl9nZW51c19JRDEgPC0gcmVsYWJfZ2VudXNfSURbLGMoMzozMSldICsgMC4wMDAwMQoKcmVsYWJfZ2VudXNfSURfbG9nIDwtIGxvZzEwKHJlbGFiX2dlbnVzX0lEX2xvZykKCgpnZW51c19TVCA8LSBjYmluZChyZWxhYl9nZW51c19JRDEsIEZBX3N0b29sLlNUKQpgYGAKCldpbGNveG9uLVRlc3QgenVyIEJlc3RpbW11bmcgdm9uIFVudGVyc2NoaWVkZSBpbSByZWxhdGl2ZW4gVm9ya29tbWVuIGRlciBHYXR0dW5nZW4gendpc2NoZW4gU8OkdHRpZ3VuZ3N0eXBlbgoKQmlmaWRvYmFjdGVyaXVtCgpgYGB7cn0KCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJGtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0sIHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0sIHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBSRSIpKSRrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19BY3Rpbm9iYWN0ZXJpYS5vX19CaWZpZG9iYWN0ZXJpYWxlcy5mX19CaWZpZG9iYWN0ZXJpYWNlYWUuZ19fQmlmaWRvYmFjdGVyaXVtLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRkFMU0UpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQT1NUIikpJGtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0sIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkPUZBTFNFKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QpKSwgYWVzKHg9UGhlbm90eXBlLHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bSkpICsgeGxhYignUGhlbm90eXBlJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JpZmlkb2JhY3Rlcml1bSknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fc2F0KSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkKCmdncGxvdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NUKSksIGFlcyh4PVRpbWUseT1rX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19BY3Rpbm9iYWN0ZXJpYS5vX19CaWZpZG9iYWN0ZXJpYWxlcy5mX19CaWZpZG9iYWN0ZXJpYWNlYWUuZ19fQmlmaWRvYmFjdGVyaXVtKSkgKyB4bGFiKCdUaW1lJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JpZmlkb2JhY3Rlcml1bSknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflBoZW5vdHlwZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKCmBgYAoKCkZhZWNhbGliYWN0ZXJpdW0KCmBgYHtyfQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJzYXQiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0sIHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInVuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQUkUiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0sIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGQUxTRSkKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBPU1QiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0sIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkPUZBTFNFKQoKZ2dwbG90KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QpKSwgYWVzKHg9UGhlbm90eXBlLHk9MTBea19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0pKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtKScpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvciA9ICdncmV5MjInKSArCiAgZmFjZXRfd3JhcCh+VGltZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl9zYXQpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpCgoKZ2dwbG90KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QpKSwgYWVzKHg9VGltZSx5PTEwXmtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtKSkgKyB4bGFiKCdUaW1lJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0pJykgKwogIGdlb21fYm94cGxvdChmaWxsID0gJ3doaXRlc21va2UnLCBjb2xvcj0iYmxhY2siKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yID0gJ2dyZXkyMicpICsKICBmYWNldF93cmFwKH5QaGVub3R5cGUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fdGltZSkrCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKQoKYGBgCgpTdXR0ZXJlbGxhCgpgYGB7cn0KCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJGtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLmNfX0JldGFwcm90ZW9iYWN0ZXJpYS5vX19CdXJraG9sZGVyaWFsZXMuZl9fQWxjYWxpZ2VuYWNlYWUuZ19fU3V0dGVyZWxsYSwgc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJzYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkka19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInVuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQUkUiKSkka19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRkFMU0UpCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBPU1QiKSkka19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZD1GQUxTRSkKCmdncGxvdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NUKSksIGFlcyh4PVBoZW5vdHlwZSx5PWtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLmNfX0JldGFwcm90ZW9iYWN0ZXJpYS5vX19CdXJraG9sZGVyaWFsZXMuZl9fQWxjYWxpZ2VuYWNlYWUuZ19fU3V0dGVyZWxsYSkpICsgeGxhYignUGhlbm90eXBlJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEpJykgKwogIGdlb21fYm94cGxvdChmaWxsID0gJ3doaXRlc21va2UnLCBjb2xvcj0iYmxhY2siKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yID0gJ2dyZXkyMicpICsKICBmYWNldF93cmFwKH5UaW1lKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSwgYWVzKGxhYmVsID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3NhdCkKCmdncGxvdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NUKSksIGFlcyh4PVRpbWUseT1rX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19CZXRhcHJvdGVvYmFjdGVyaWEub19fQnVya2hvbGRlcmlhbGVzLmZfX0FsY2FsaWdlbmFjZWFlLmdfX1N1dHRlcmVsbGEpKSArIHhsYWIoJ1RpbWUnKSArIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYSknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflBoZW5vdHlwZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKYGBgCgpPc2NpbGxvc3BpcmEKSW4gQXJiZWl0CgpgYGB7cn0KCm1lYW4oc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAic2F0IikpJGtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEpIAoKc2Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAic2F0IikpJGtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEpIAoKbWVhbihzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAic2F0IikpJGtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEpIAoKc2Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gInNhdCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhKQoKCm1lYW4oc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnNhdCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhKSAKCnNkKHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSkgCgptZWFuKHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJGtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEpIAoKc2Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSkgCgoKCm1lYW4oc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSkgCgpzZChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhKSAKCm1lYW4oc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gInVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEpIAoKc2Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gInVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEpCgoKbWVhbihzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSkgCgpzZChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSkKCm1lYW4oc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhKSAKCnNkKHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSkKCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInVuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSwgc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUFJFIikpJGtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEsIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGQUxTRSkKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBPU1QiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSwgc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBPU1QiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQ9RkFMU0UpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCkpLCBhZXMoeD1QaGVub3R5cGUseT0xMF5rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhKSkgKyB4bGFiKCdQaGVub3R5cGUnKSArIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhKScpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvciA9ICdncmV5MjInKSArCiAgZmFjZXRfd3JhcCh+VGltZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl9zYXQpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpCgoKcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL3NhdC50eXBlcy5vc2NpbGxvLm5ldS5wZGYiLHdpZHRoPTgsIGhlaWdodD0xMCkKZ2dwbG90KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QpKSwgYWVzKHg9UGhlbm90eXBlLHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSwgZmlsbD0gUGhlbm90eXBlKSkgKyAKICB4bGFiKCdQaMOkbm90eXAnKSArIHlsYWIoJ1JlbGF0aXZlcyBWb3Jrb21tZW4gZ19fT3NjaWxsb3NwaXJhIFslXScpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAuNywgbHdkPTAuNikgKyB0aGVtZV9jbGFzc2ljKCkrCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiY2hhbmdlLnNhdCIgPSAienUgZ2Vzw6R0dGlndCIsICJjaGFuZ2UudW5zYXQiID0gInp1IHVuZ2Vzw6R0dGlndCIsICJzYXQiID0gImdlc8OkdHRpZ3QiLCAidW5zYXQiPSAidW5nZXPDpHR0aWd0IikpKwogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscyA9IGMoIndlY2hzZWwgenUgZ2Vzw6R0dGlndCIsICJ3ZWNoc2VsIHp1IHVuZ2Vzw6R0dGlndCIsICJnZXPDpHR0aWd0IiwgInVuZ2Vzw6R0dGlndCIpLAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoImxpZ2h0c2t5Ymx1ZTQiLCAibGlnaHRza3libHVlMyIsICJsaWdodHNreWJsdWUyIiwgImxpZ2h0c2t5Ymx1ZSIpKSsKICBmYWNldF93cmFwKH5UaW1lKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSwgYWVzKGxhYmVsID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3NhdCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT00NSwgaGp1c3Q9MSkpKwogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoKSkKZGV2Lm9mZigpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCkpLCBhZXMoeD1UaW1lLHk9a19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYSkpICsgeGxhYignVGltZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEpJykgKwogIGdlb21fYm94cGxvdChmaWxsID0gJ3doaXRlc21va2UnLCBjb2xvcj0iYmxhY2siKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yID0gJ2dyZXkyMicpICsKICBmYWNldF93cmFwKH5QaGVub3R5cGUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fdGltZSkKCgpgYGAKCkFra2VybWFuc2lhCkluIEFyYmVpdAoKYGBge3J9CgptZWFuKHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gInNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYSkgCgpzZChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJzYXQiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEpIAoKbWVhbihzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAic2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhKSAKCnNkKHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJzYXQiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEpIAoKCm1lYW4oc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYSkgCgpzZChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhKSAKCm1lYW4oc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEpIAoKc2Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEpIAoKCgptZWFuKHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gInVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhKSAKCnNkKHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gInVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhKSAgCgptZWFuKHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYSkgCgpzZChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEpCgoKbWVhbihzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEpIAoKc2Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhKSAKCm1lYW4oc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYSkgCgpzZChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhKQoKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYSwgc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUFJFIikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRkFMU0UpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQT1NUIikpJGtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZD1GQUxTRSkKCmdncGxvdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NUKSksIGFlcyh4PVBoZW5vdHlwZSx5PTEwXmtfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhKSkgKyB4bGFiKCdQaGVub3R5cGUnKSArIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQWtrZXJtYW5zaWEpJykgKwogIGdlb21fYm94cGxvdChmaWxsID0gJ3doaXRlc21va2UnLCBjb2xvcj0iYmxhY2siKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yID0gJ2dyZXkyMicpICsKICBmYWNldF93cmFwKH5UaW1lKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSwgYWVzKGxhYmVsID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3NhdCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoKSkKCnBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9zYXQudHlwZXMuYWtrZXJtYW5zaWEubmV1LnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCkpLCBhZXMoeD1QaGVub3R5cGUseT1rX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYSwgZmlsbD0gUGhlbm90eXBlKSkgKyAKICB4bGFiKCdQaMOkbm90eXAnKSArIHlsYWIoJ1JlbGF0aXZlcyBWb3Jrb21tZW4gZ19fQWtrZXJtYW5zaWEgWyVdJykgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IC43LCBsd2Q9MC42KSArIHRoZW1lX2NsYXNzaWMoKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJjaGFuZ2Uuc2F0IiA9ICJ6dSBnZXPDpHR0aWd0IiwgImNoYW5nZS51bnNhdCIgPSAienUgdW5nZXPDpHR0aWd0IiwgInNhdCIgPSAiZ2Vzw6R0dGlndCIsICJ1bnNhdCI9ICJ1bmdlc8OkdHRpZ3QiKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygid2VjaHNlbCB6dSBnZXPDpHR0aWd0IiwgIndlY2hzZWwgenUgdW5nZXPDpHR0aWd0IiwgImdlc8OkdHRpZ3QiLCAidW5nZXPDpHR0aWd0IiksCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygibGlnaHRza3libHVlNCIsICJsaWdodHNreWJsdWUzIiwgImxpZ2h0c2t5Ymx1ZTIiLCAibGlnaHRza3libHVlIikpKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9ICkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT00NSwgaGp1c3Q9MSkpKwogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoKSkKZGV2Lm9mZigpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCkpLCBhZXMoeD1UaW1lLHk9MTBea19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEpKSArIHhsYWIoJ1RpbWUnKSArIHlsYWIoJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQWtrZXJtYW5zaWEpJykgKwogIGdlb21fYm94cGxvdChmaWxsID0gJ3doaXRlc21va2UnLCBjb2xvcj0iYmxhY2siKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yID0gJ2dyZXkyMicpICsKICBmYWNldF93cmFwKH5QaGVub3R5cGUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fdGltZSkrCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKQoKYGBgCgpCYWN0ZXJvaWRlcwoKYGBge3J9CgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMsIHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInVuc2F0IikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19CYWN0ZXJvaWRhY2VhZS5nX19CYWN0ZXJvaWRlcywgc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUFJFIikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19CYWN0ZXJvaWRhY2VhZS5nX19CYWN0ZXJvaWRlcywgc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRkFMU0UpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQT1NUIikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19CYWN0ZXJvaWRhY2VhZS5nX19CYWN0ZXJvaWRlcywgc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUE9TVCIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZD1GQUxTRSkKCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCkpLCBhZXMoeD1QaGVub3R5cGUseT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMpKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CYWN0ZXJvaWRlcyknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fc2F0KQoKZ2dwbG90KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QpKSwgYWVzKHg9VGltZSx5PWtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19CYWN0ZXJvaWRhY2VhZS5nX19CYWN0ZXJvaWRlcykpICsgeGxhYignVGltZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CYWN0ZXJvaWRlcyknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflBoZW5vdHlwZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKYGBgCgpQcmV2b3RlbGxhCgpgYGB7cn0KCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19QcmV2b3RlbGxhY2VhZS5nX19QcmV2b3RlbGxhLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUHJldm90ZWxsYWNlYWUuZ19fUHJldm90ZWxsYSwgc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUFJFIikpJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19QcmV2b3RlbGxhY2VhZS5nX19QcmV2b3RlbGxhLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQUkUiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGQUxTRSkKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBPU1QiKSkka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX1ByZXZvdGVsbGFjZWFlLmdfX1ByZXZvdGVsbGEsIHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBPU1QiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQ9RkFMU0UpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCkpLCBhZXMoeD1QaGVub3R5cGUseT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUHJldm90ZWxsYWNlYWUuZ19fUHJldm90ZWxsYSkpICsgeGxhYignUGhlbm90eXBlJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1ByZXZvdGVsbGEpJykgKwogIGdlb21fYm94cGxvdChmaWxsID0gJ3doaXRlc21va2UnLCBjb2xvcj0iYmxhY2siKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yID0gJ2dyZXkyMicpICsKICBmYWNldF93cmFwKH5UaW1lKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSwgYWVzKGxhYmVsID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3NhdCkKCmdncGxvdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NUKSksIGFlcyh4PVRpbWUseT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUHJldm90ZWxsYWNlYWUuZ19fUHJldm90ZWxsYSkpICsgeGxhYignVGltZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19QcmV2b3RlbGxhKScpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvciA9ICdncmV5MjInKSArCiAgZmFjZXRfd3JhcCh+UGhlbm90eXBlKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSwgYWVzKGxhYmVsID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX3RpbWUpCgpgYGAKCkRvcmVhCgpgYGB7cn0KcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJzYXQiKSkka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0RvcmVhLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEsIHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBSRSIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEsIHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBSRSIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUE9TVCIpKSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEsIHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBPU1QiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQ9RkFMU0UpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCkpLCBhZXMoeD1QaGVub3R5cGUseT1rX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEpKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Eb3JlYSknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflRpbWUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fc2F0KQoKZ2dwbG90KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QpKSwgYWVzKHg9VGltZSx5PWtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYSkpICsgeGxhYignVGltZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Eb3JlYSknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflBoZW5vdHlwZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKYGBgCgpDb2xsaW5zZWxsYQoKYGBge3J9CgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19Db3Jpb2JhY3RlcmlpYS5vX19Db3Jpb2JhY3RlcmlhbGVzLmZfX0NvcmlvYmFjdGVyaWFjZWFlLmdfX0NvbGxpbnNlbGxhLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19Db3Jpb2JhY3RlcmlpYS5vX19Db3Jpb2JhY3RlcmlhbGVzLmZfX0NvcmlvYmFjdGVyaWFjZWFlLmdfX0NvbGxpbnNlbGxhLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInVuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQUkUiKSkka19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQ29yaW9iYWN0ZXJpaWEub19fQ29yaW9iYWN0ZXJpYWxlcy5mX19Db3Jpb2JhY3RlcmlhY2VhZS5nX19Db2xsaW5zZWxsYSwgc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRkFMU0UpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBUaW1lID09ICJQT1NUIikpJGtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0NvcmlvYmFjdGVyaWlhLm9fX0NvcmlvYmFjdGVyaWFsZXMuZl9fQ29yaW9iYWN0ZXJpYWNlYWUuZ19fQ29sbGluc2VsbGEsIHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBPU1QiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQ9RkFMU0UpCgoKZ2dwbG90KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QpKSwgYWVzKHg9UGhlbm90eXBlLHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQ29yaW9iYWN0ZXJpaWEub19fQ29yaW9iYWN0ZXJpYWxlcy5mX19Db3Jpb2JhY3RlcmlhY2VhZS5nX19Db2xsaW5zZWxsYSkpICsgeGxhYignUGhlbm90eXBlJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvbGxpbnNlbGxhKScpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvciA9ICdncmV5MjInKSArCiAgZmFjZXRfd3JhcCh+VGltZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl9zYXQpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCkpLCBhZXMoeD1UaW1lLHk9a19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQ29yaW9iYWN0ZXJpaWEub19fQ29yaW9iYWN0ZXJpYWxlcy5mX19Db3Jpb2JhY3RlcmlhY2VhZS5nX19Db2xsaW5zZWxsYSkpICsgeGxhYignVGltZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db2xsaW5zZWxsYSknKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAnd2hpdGVzbW9rZScsIGNvbG9yPSJibGFjayIpICsgCiAgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAneScsIHN0YWNrZGlyID0gJ2NlbnRlcicsIGRvdHNpemUgPSAwLjIsIGZpbGwgPSAnZ3JleTIyJywgY29sb3IgPSAnZ3JleTIyJykgKwogIGZhY2V0X3dyYXAoflBoZW5vdHlwZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQoKYGBgCgpSaWtlbmVsbGFjZWFlCgpgYGB7cn0KcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJzYXQiKSkka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX1Jpa2VuZWxsYWNlYWUuZ19fLCBzdWJzZXQoZmlsdGVyKGdlbnVzX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUmlrZW5lbGxhY2VhZS5nX18sIHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBSRSIpKSRrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUmlrZW5lbGxhY2VhZS5nX18sIHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBSRSIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEZBTFNFKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCwgVGltZSA9PSAiUE9TVCIpKSRrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUmlrZW5lbGxhY2VhZS5nX18sIHN1YnNldChmaWx0ZXIoZ2VudXNfU1QsIFRpbWUgPT0gIlBPU1QiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQ9RkFMU0UpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCkpLCBhZXMoeD1QaGVub3R5cGUseT1rX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUmlrZW5lbGxhY2VhZS5nX18pKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBmX19SaWtlbmVsbGFjZWFlKScpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvciA9ICdncmV5MjInKSArCiAgZmFjZXRfd3JhcCh+VGltZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl9zYXQpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihnZW51c19TVCkpLCBhZXMoeD1UaW1lLHk9a19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX1Jpa2VuZWxsYWNlYWUuZ19fKSkgKyB4bGFiKCdUaW1lJykgKyB5bGFiKCdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGZfX1Jpa2VuZWxsYWNlYWUpJykgKwogIGdlb21fYm94cGxvdChmaWxsID0gJ3doaXRlc21va2UnLCBjb2xvcj0iYmxhY2siKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yID0gJ2dyZXkyMicpICsKICBmYWNldF93cmFwKH5QaGVub3R5cGUpICsgCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFLCBhZXMobGFiZWwgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9IGNvbXBhcmlzb25fdGltZSkKCgoKRkFfc3Rvb2wuUFJFIDwtIHN1YnNldChmaWx0ZXIoRkFfc3Rvb2wuU1QsIFRpbWUgPT0gIlBSRSIpKQoKRkFfc3Rvb2wuUE9TVCA8LSBzdWJzZXQoZmlsdGVyKEZBX3N0b29sLlNULCBUaW1lID09ICJQT1NUIikpCgpgYGAKClVudGVyc2NoaWVkZSBpbSBGaXJtaWN1dGVzL0JhY3Rlcm9pZGV0ZXMtcmF0aW8gendpc2NoZW4gZGVuIFPDpHR0aWd1bmdzdHlwZW4KCkxhZGVuIGRlciBNZXRhZGF0ZW4sIEJlc3RpbW1lbiB2b24gTWVhbiB1bmQgU0QKCmBgYHtyfQoKcGh5bHVtX1NUIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZhIGZlY2VzL0ZBIGZlY2FsL3NhdHVyYXRpb24gdHlwZXMvcGh5bHVtLnBoZW5vdHlwZS50eHQiLCBzZXAgPSdcdCcsIGNvbW1lbnQ9JycsIGhlYWQ9VCkKCnBoeWx1bV9TVCRUaW1lIDwtZmFjdG9yKHBoeWx1bV9TVCRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKCm1lYW4oc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gInNhdCIpKSRGX0JfcmF0aW8pIAoKc2Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gInNhdCIpKSRGX0JfcmF0aW8pCgptZWFuKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAic2F0IikpJEZfQl9yYXRpbykgCgpzZChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gInNhdCIpKSRGX0JfcmF0aW8pIAoKCm1lYW4oc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkkRl9CX3JhdGlvKSAKCnNkKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJEZfQl9yYXRpbykgCgptZWFuKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnNhdCIpKSRGX0JfcmF0aW8pIAoKc2Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJjaGFuZ2Uuc2F0IikpJEZfQl9yYXRpbykgCgoKCm1lYW4oc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gInVuc2F0IikpJEZfQl9yYXRpbykgCgpzZChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUFJFIiAmIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkRl9CX3JhdGlvKSAgCgptZWFuKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkRl9CX3JhdGlvKSAKCnNkKHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkRl9CX3JhdGlvKQoKCm1lYW4oc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRGX0JfcmF0aW8pIAoKc2Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRGX0JfcmF0aW8pIAoKbWVhbihzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIgJiBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRGX0JfcmF0aW8pIAoKc2Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJjaGFuZ2UudW5zYXQiKSkkRl9CX3JhdGlvKQoKYGBgCgpXaWxjb3hvbi1UZXN0IHp1ciBCZXN0aW1tdW5nIHZvbiBVbnRlcnNjaGllZGUgaW0gRi9CLXJhdGlvIHp3aXNjaGVuIFPDpHR0aWd1bmdzdHlwZW4KCkluIEFyYmVpdAoKYGBge3J9CgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUFJFIikpJEZfQl9yYXRpbywgc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFRpbWUgPT0gIlBSRSIpKSRQaGVub3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgVGltZSA9PSAiUE9TVCIpKSRGX0JfcmF0aW8sIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBUaW1lID09ICJQT1NUIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRGX0JfcmF0aW8sIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gInNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFBoZW5vdHlwZSA9PSAidW5zYXQiKSkkRl9CX3JhdGlvLCBzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFBoZW5vdHlwZSA9PSAiY2hhbmdlLnNhdCIpKSRGX0JfcmF0aW8sIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gImNoYW5nZS5zYXQiKSkkVGltZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRGX0JfcmF0aW8sIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gImNoYW5nZS51bnNhdCIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJEZfQl9yYXRpbywgc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QsIFBoZW5vdHlwZSA9PSAic2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCwgUGhlbm90eXBlID09ICJ1bnNhdCIpKSRGX0JfcmF0aW8sIHN1YnNldChmaWx0ZXIocGh5bHVtX1NULCBQaGVub3R5cGUgPT0gInVuc2F0IikpJFRpbWUsIHAuYWRqdXN0Lm1ldGhvZCA9ICdCSCcsIHBhaXJlZCA9IEYpCgpnZ3Bsb3Qoc3Vic2V0KGZpbHRlcihwaHlsdW1fU1QpKSwgYWVzKHg9UGhlbm90eXBlLHk9Rl9CX3JhdGlvKSkgKyB4bGFiKCdQaGVub3R5cGUnKSArIHlsYWIoJ0Zpcm1pY3V0ZXMvQmFjdGVyb2lkZXRlcyByYXRpbycpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvciA9ICdncmV5MjInKSArCiAgZmFjZXRfd3JhcCh+VGltZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl9zYXQpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL3NhdC50eXBlcy5GLkIucGRmIix3aWR0aD04LCBoZWlnaHQ9MTApCmdncGxvdChzdWJzZXQoZmlsdGVyKHBoeWx1bV9TVCkpLCBhZXMoeD1QaGVub3R5cGUseT1GX0JfcmF0aW8sIGZpbGw9IFBoZW5vdHlwZSkpICsgCiAgeGxhYignUGhlbm90eXBlJykgKyB5bGFiKCdGaXJtaWN1dGVzL0JhY3Rlcm9pZGV0ZXMgVmVyaMOkbHRuaXMnKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gLjcsIGx3ZD0wLjYpICsgdGhlbWVfY2xhc3NpYygpKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoImNoYW5nZS5zYXQiID0gInp1IGdlc8OkdHRpZ3QiLCAiY2hhbmdlLnVuc2F0IiA9ICJ6dSB1bmdlc8OkdHRpZ3QiLCAic2F0IiA9ICJnZXPDpHR0aWd0IiwgInVuc2F0Ij0gInVuZ2Vzw6R0dGlndCIpKSsKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJ3ZWNoc2VsIHp1IGdlc8OkdHRpZ3QiLCAid2VjaHNlbCB6dSB1bmdlc8OkdHRpZ3QiLCAiZ2Vzw6R0dGlndCIsICJ1bmdlc8OkdHRpZ3QiKSwKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJsaWdodHNreWJsdWU0IiwgImxpZ2h0c2t5Ymx1ZTMiLCAibGlnaHRza3libHVlMiIsICJsaWdodHNreWJsdWUiKSkrCiAgZmFjZXRfd3JhcCh+VGltZSkgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl9zYXQpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0PTEpKQpkZXYub2ZmKCkKCnR5cGVzIDwtIG1lbHQocGh5bHVtX1NULCBpZC52YXJzID0gYygnVGltZScsICdGX0JfcmF0aW8nKSwgbWVhc3VyZS52YXJzID0gYygnc2F0JywgJ3Vuc2F0JykpCgp0eXBlcy5wciA8LSBzdWJzZXQoZmlsdGVyKHR5cGVzLCAhVGltZSA9PSAnUE9TVCcpKQoKdHlwZXMucG8gPC0gc3Vic2V0KGZpbHRlcih0eXBlcywgIVRpbWUgPT0gJ1BSRScpKQoKdHlwZXMgPC1kcGx5cjo6cmVuYW1lKHR5cGVzLCBGQT12YXJpYWJsZSkKICAgICAgICAgICAgICAgICAgICAgIAp0eXBlcyA8LSBkcGx5cjo6cmVuYW1lKHR5cGVzLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoY29udlQsIFRpbWUgPT0gIlBSRSIpKSRGX0JfcmF0aW8sIHN1YnNldChmaWx0ZXIoY29udlQsIFRpbWUgPT0gIlBSRSIpKSRQaGVub3R5cGUyLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihjb252VCwgVGltZSA9PSAiUE9TVCIpKSRGX0JfcmF0aW8sIHN1YnNldChmaWx0ZXIoY29udlQsIFRpbWUgPT0gIlBPU1QiKSkkUGhlbm90eXBlMiwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCgpnZ3NjYXR0ZXIodHlwZXMucHIsIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdGX0JfcmF0aW8nLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicsICdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicsICdjeWFuJywneWVsbG93JyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5zaXplID0gNiwgeGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnRmlybWljdXRlcy9CYWN0ZXJvaWRldGVzIHJhdGlvJykrCiAgZmFjZXRfZ3JpZCgufiBGQSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1BSRScpKwp0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKCnBoeWx1bV9TVCRUaW1lIDwtIGZhY3RvcihwaHlsdW1fU1QkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCnBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9zYXQuYmFjdC5maXJtLnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQpnZ3NjYXR0ZXIocGh5bHVtX1NULCB4PSdzYXQnLCB5PSdGX0JfcmF0aW8nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygnc2t5Ymx1ZScsICdvcmNoaWQnKSwgIGFkZCA9ICdyZWcubGluZScsIHNpemU9Mi41LGNvci5jb2VmLmNvb3JkID1jKDI1MCwgMTkpLGNvci5jb2VmLnNpemUgPSA3LGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnR2Vzw6R0dGlndGUgRmV0dHPDpHVyZW5rb256ZW50cmF0aW9uZW4gW25tb2wvZ10nLCB5bGFiID0gJ0Zpcm1pY3V0ZXMvQmFjdGVyb2lkZXRlcyBWZXJow6RsdG5pcycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQpkZXYub2ZmKCkKCgpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvdW5zYXQuYmFjdC5maXJtLnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQpnZ3NjYXR0ZXIocGh5bHVtX1NULCB4PSd1bnNhdCcsIHk9J0ZfQl9yYXRpbycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCdza3libHVlJywgJ29yY2hpZCcpLCAgYWRkID0gJ3JlZy5saW5lJyxzaXplPTIuNSwgY29yLmNvZWYuY29vcmQgPWMoMjUwLCAxOSksY29yLmNvZWYuc2l6ZSA9IDcsY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdVbmdlc8OkdHRpZ3RlIEZldHRzw6R1cmVua29uemVudHJhdGlvbmVuIFtubW9sL2ddJywgeWxhYiA9ICdGaXJtaWN1dGVzL0JhY3Rlcm9pZGV0ZXMgVmVyaMOkbHRuaXMnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0wLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKZGV2Lm9mZigpCgoKZ2dzY2F0dGVyKHR5cGVzLnBvLCB4PSdDb25jZW50cmF0aW9uJywgeT0nRl9CX3JhdGlvJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nLCAnc3RlZWxibHVlMicsICdkZWVwcGluazInLCAnY3lhbicsJ3llbGxvdycpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYyg1MDAsIDYpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ0Zpcm1pY3V0ZXMvQmFjdGVyb2lkZXRlcyByYXRpbycpKwogIGZhY2V0X2dyaWQoLn4gRkEpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQT1NUJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcih0eXBlcywgeD0nQ29uY2VudHJhdGlvbicsIHk9J0ZfQl9yYXRpbycsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJywgJ3N0ZWVsYmx1ZTInLCAnZGVlcHBpbmsyJywgJ2N5YW4nLCd5ZWxsb3cnKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoNTAwLCAxNiksY29yLmNvZWYuc2l6ZSA9IDYseGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnRmlybWljdXRlcy9CYWN0ZXJvaWRldGVzIHJhdGlvJykrCiAgZmFjZXRfZ3JpZCgufiBGQSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1RpbWVzIHRvZ2V0aGVyJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCgoKYGBgCgo1LiBBbmFseXNlbiBtaXQgZGVtIEZpcm1pY3V0ZXMvQmFjdGVyb2lkZXRlcy1yYXRpbwpVbnRlcnNjaGllZGUgaW0gRi9CLXJhdGlvIHp3aXNjaGVuIFN0ZXJvbGtvbnZlcnRpZXJ1bmdzdHlwZW4KVW50ZXJ0ZWlsZW4gaW4gaGlnaCB1bmQgbG93IGNvbnZlcnRlcgoKYGBge3J9Cmxvd2NvbnYgPC0gZmlsdGVyKHBoeWx1bV9TVCwgUHJvYmFuZCA9PSAiMDVBUCIgfCBQcm9iYW5kID09ICIzM01QIgogICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzOEFSIiB8IFByb2JhbmQgPT0gIjQwV0EiIHwgUHJvYmFuZCA9PSAiNDFNTCIKICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNDdPVCIgfCBQcm9iYW5kID09ICI0OVJKIiB8IFByb2JhbmQgPT0gIjUwRE0iKQoKbG93Y29udlsnUGhlbm90eXBlMiddID0gJ2xvdyBjb252ZXJ0ZXInCgpoaWdoY29udiA8LSBmaWx0ZXIocGh5bHVtX1NULCBQcm9iYW5kID09ICIwNldUIiB8IFByb2JhbmQgPT0gIjA3UlciCiAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMTNCUyIgfCBQcm9iYW5kID09ICIxN1NLIiB8IFByb2JhbmQgPT0gIjIyV1MiCiAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMjVGRSIgfCBQcm9iYW5kID09ICIyNkZCIiB8IFByb2JhbmQgPT0gIjI5TUsiCiAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzBIQiIgfCBQcm9iYW5kID09ICIzMUtFIiB8IFByb2JhbmQgPT0gIjM2RVIiCiAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNDVHTCIgfCBQcm9iYW5kID09ICI1M0JEIiB8IFByb2JhbmQgPT0gIjU0U0wiCiAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNTdNVCIgfCBQcm9iYW5kID09ICI2OUhMIiB8IFByb2JhbmQgPT0gIjc0U0EiKQoKaGlnaGNvbnZbJ1BoZW5vdHlwZTInXSA9ICdoaWdoIGNvbnZlcnRlcicKCmhpZ2hjb252JENvbnZlcnRlci5UeXBlIDwtIE5VTEwKbG93Y29udiRDb252ZXJ0ZXIuVHlwZSA8LSBOVUxMCgpub2NvbnYgPC0gZmlsdGVyKHBoeWx1bV9TVCwgUHJvYmFuZCA9PSAiMjhITSIgfCBQcm9iYW5kID09ICIzMkZHIgogICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzRXRiIgfCBQcm9iYW5kID09ICIzNUFEIiB8IFByb2JhbmQgPT0gIjM3U0QiCiAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzOURBIiB8IFByb2JhbmQgPT0gIjY2REciIHwgUHJvYmFuZCA9PSAiNzBQTCIpCgpub2NvbnZbJ1BoZW5vdHlwZTInXSA9ICdub3QgY2xhc3NpZmllZCcKCm5vY29udiRDb252ZXJ0ZXIuVHlwZSA8LSBOVUxMCgpjb252VCA8LSBkYXRhLmZyYW1lKCkKY29udlQgPC0gYmluZF9yb3dzKGxvd2NvbnYsIGhpZ2hjb252LCBub2NvbnYpCgpjb21wYXJpc29uX2NvbnYgPC0gbGlzdChjKCJsb3cgY29udmVydGVyIiwgImhpZ2ggY29udmVydGVyIikpCgpjb252VCA8LSBzdWJzZXQoZmlsdGVyKGNvbnZULCAhUGhlbm90eXBlMiA9PSAnbm90IGNsYXNzaWZpZWQnKSkKCnBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoY29udlQsIFRpbWUgPT0gIlBSRSIpKSRGX0JfcmF0aW8sIHN1YnNldChmaWx0ZXIoY29udlQsIFRpbWUgPT0gIlBSRSIpKSRQaGVub3R5cGUyLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQoKcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihjb252VCwgVGltZSA9PSAiUE9TVCIpKSRGX0JfcmF0aW8sIHN1YnNldChmaWx0ZXIoY29udlQsIFRpbWUgPT0gIlBPU1QiKSkkUGhlbm90eXBlMiwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKCmdncGxvdChzdWJzZXQoZmlsdGVyKGNvbnZUKSksIGFlcyh4PVBoZW5vdHlwZTIseT1GX0JfcmF0aW8pKSArIHhsYWIoJ1BoZW5vdHlwZScpICsgeWxhYignRmlybWljdXRlcy9CYWN0ZXJvaWRldGVzIHJhdGlvJykgKwogIGdlb21fYm94cGxvdChmaWxsID0gJ3doaXRlc21va2UnLCBjb2xvcj0iYmxhY2siKSArIAogIGdlb21fZG90cGxvdChiaW5heGlzID0gJ3knLCBzdGFja2RpciA9ICdjZW50ZXInLCBkb3RzaXplID0gMC4yLCBmaWxsID0gJ2dyZXkyMicsIGNvbG9yID0gJ2dyZXkyMicpICsKICBmYWNldF93cmFwKH5UaW1lKSArIAogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSwgYWVzKGxhYmVsID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPSBjb21wYXJpc29uX2NvbnYpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKQoKCmdncGxvdChzdWJzZXQoZmlsdGVyKGNvbnZUKSksIGFlcyh4PVRpbWUseT1GX0JfcmF0aW8pKSArIHhsYWIoJ1RpbWUnKSArIHlsYWIoJ0Zpcm1pY3V0ZXMvQmFjdGVyb2lkZXRlcyByYXRpbycpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICd3aGl0ZXNtb2tlJywgY29sb3I9ImJsYWNrIikgKyAKICBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICd5Jywgc3RhY2tkaXIgPSAnY2VudGVyJywgZG90c2l6ZSA9IDAuMiwgZmlsbCA9ICdncmV5MjInLCBjb2xvciA9ICdncmV5MjInKSArCiAgZmFjZXRfd3JhcCh+UGhlbm90eXBlMikgKyAKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UsIGFlcyhsYWJlbCA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID0gY29tcGFyaXNvbl90aW1lKQpgYGAKCktvcnJlbGF0aW9uc2FuYWx5c2VuIHp3aXNjaGVuIGFsbGVuIGbDpGthbGVuIEZldHRzw6R1cmVuIHVuZCBkZW0gRi9CLXJhdGlvCkxvb3AgdW5kIFBsb3RzIHp1IGdlc8OkdHRpZ3RlIEZldHRzw6R1cmVuIHVuZCBGL0ItcmF0aW8KSW4gQXJiZWl0CgpgYGB7cn0KCnBoeWx1bV9jb2xuYW1lcyA8LSBjb2xuYW1lcyhwaHlsdW1fU1RbLCBjKDM6OSldKQoKY29ycl9tYXBfcGh5bHVtX3NhdCA8LSBmaWx0ZXIocGh5bHVtX1NULCAhaXMubmEoc2F0KSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdCA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBwaHlsdW1fY29sbmFtZXMpIHsKICAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9zYXQsICFpcy5uYShpKSkKCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJHNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQoKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCgogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJHNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkc2F0CiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXQpKzEKCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fc2F0W25yb3csIkZBIl0gPC0gInNhdCIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXRbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdFtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXRbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdFtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXRbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXQkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXQkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdCRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9zYXQkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdCRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fc2F0JHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCmNvcnJfc2lnX1BoeWx1bV9zYXQgPC0gZmlsdGVyKGNvcnJfc3BlYXJtYW5fUGh5bHVtX3NhdCwgcC5hZGp1c3RlZCA8IDAuMDUgfCBwLmFkanVzdGVkX1BSRSA8IDAuMDUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjA1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9QaHlsdW1fc2F0LCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL0ZCIHEtdmFsdWUvc2F0LnBoeWx1bS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpnZ3NjYXR0ZXIocGh5bHVtX1NULCB4PSdzYXQnLCB5PSdGX0JfcmF0aW8nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ3NhdHVyYXRlZCBmYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ0Zpcm1pY3V0ZXMvQmFjdGVyb2lkZXRlcyByYXRpbycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKZ2dzY2F0dGVyKHBoeWx1bV9TVCwgeD0nc2F0JywgeT0nRl9CX3JhdGlvJywgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnc2F0dXJhdGVkIGZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnRmlybWljdXRlcy9CYWN0ZXJvaWRldGVzIHJhdGlvJykrCiAKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvc2F0LmJhY3QuZmlybS5wZGYiLHdpZHRoPTgsIGhlaWdodD0xMCkKZ2dzY2F0dGVyKHBoeWx1bV9TVCwgeD0nc2F0JywgeT0nRl9CX3JhdGlvJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3NreWJsdWUnLCAnb3JjaGlkJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb3IuY29lZi5jb29yZCA9YygyNTAsIDE5KSxjb3IuY29lZi5zaXplID0gNyxjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0dlc8OkdHRpZ3RlIEZldHRzw6R1cmVua29uemVudHJhdGlvbmVuIFtubW9sL2ddJywgeWxhYiA9ICdGaXJtaWN1dGVzL0JhY3Rlcm9pZGV0ZXMgVmVyaMOkbHRuaXMnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0wLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKZGV2Lm9mZigpCgpgYGAKCkxvb3AgdW5kIFBsb3RzIHp1IHVuZ2Vzw6R0dGlndGUgRmV0dHPDpHVyZW4gdW5kIEYvQi1yYXRpbwoKYGBge3J9CgpwaHlsdW1fY29sbmFtZXMgPC0gY29sbmFtZXMocGh5bHVtX1NUWywgYygzOjkpXSkKCmNvcnJfbWFwX3BoeWx1bV91bnNhdCA8LSBmaWx0ZXIocGh5bHVtX1NULCAhaXMubmEodW5zYXQpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CgogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX3Vuc2F0LCAhaXMubmEoaSkpCiAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkdW5zYXQKCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkdW5zYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSR1bnNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCgogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0KSsxCiAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdFtucm93LCJGQSJdIDwtICJ1bnNhdCIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdFtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXRbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdFtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXRbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdFtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0JHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0JHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0JHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdCRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKY29ycl9zaWdfUGh5bHVtX3Vuc2F0IDwtIGZpbHRlcihjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdCwgcC5hZGp1c3RlZCA8IDAuMDUgfCBwLmFkanVzdGVkX1BSRSA8IDAuMDUgfCBwLmFkanVzdGVkX1BPU1QgPCAwLjA1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvRkIgcS12YWx1ZS91bnNhdC5waHlsdW0udHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKYGBgCgpQbG90cyB6dSBlaW5mYWNoIHVuZ2Vzw6R0dGlndGVuIEZBIHVuZCBGL0ItcmF0aW8gCgpgYGB7cn0KZ2dzY2F0dGVyKHBoeWx1bV9TVCwgeD0nbW9uby51bnNhdCcsIHk9J0ZfQl9yYXRpbycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTW9ub3Vuc2F0dXJhdGVkIGZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnRmlybWljdXRlcy9CYWN0ZXJvaWRldGVzIHJhdGlvJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgpnZ3NjYXR0ZXIocGh5bHVtX1NULCB4PSdtb25vLnVuc2F0JywgeT0nRl9CX3JhdGlvJywgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTW9ub3Vuc2F0dXJhdGVkIGZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnRmlybWljdXRlcy9CYWN0ZXJvaWRldGVzIHJhdGlvJykrCiAgCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmBgYAoKUGxvdHMgenUgendlaWZhY2ggdW5nZXPDpHR0aWd0ZW4gRkEgLSB0b3RhbCBGQSB1bmQgRi9CLXJhdGlvIAoKYGBge3J9CgpnZ3NjYXR0ZXIocGh5bHVtX1NULCB4PSdkaS51bnNhdCcsIHk9J0ZfQl9yYXRpbycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnRGl1bnNhdHVyYXRlZCBmYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ0Zpcm1pY3V0ZXMvQmFjdGVyb2lkZXRlcyByYXRpbycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKZ2dzY2F0dGVyKHBoeWx1bV9TVCwgeD0nZGkudW5zYXQnLCB5PSdGX0JfcmF0aW8nLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdEaXVuc2F0dXJhdGVkIGZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnRmlybWljdXRlcy9CYWN0ZXJvaWRldGVzIHJhdGlvJykrCiAgCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKZ2dzY2F0dGVyKHBoeWx1bV9TVCwgeD0nbW9yZS4yLnVuc2F0JywgeT0nRl9CX3JhdGlvJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICc+IDIgdW5zYXR1cmF0ZWQgZmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdGaXJtaWN1dGVzL0JhY3Rlcm9pZGV0ZXMgcmF0aW8nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmdnc2NhdHRlcihwaHlsdW1fU1QsIHg9J21vcmUuMi51bnNhdCcsIHk9J0ZfQl9yYXRpbycsICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJz4gMiB1bnNhdHVyYXRlZCBmYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ0Zpcm1pY3V0ZXMvQmFjdGVyb2lkZXRlcyByYXRpbycpKwogIAogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmdnc2NhdHRlcihwaHlsdW1fU1QsIHg9J2xlc3MuMTQnLCB5PSdGX0JfcmF0aW8nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJzwgMTQgYyBhdG9tZXMgZmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdGaXJtaWN1dGVzL0JhY3Rlcm9pZGV0ZXMgcmF0aW8nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmdnc2NhdHRlcihwaHlsdW1fU1QsIHg9J21vcmUuMi51bnNhdCcsIHk9J0ZfQl9yYXRpbycsICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJz4gMiB1bnNhdHVyYXRlZCBmYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ0Zpcm1pY3V0ZXMvQmFjdGVyb2lkZXRlcyByYXRpbycpKwogIAogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmdnc2NhdHRlcihwaHlsdW1fU1QsIHg9J2MxNC4xNycsIHk9J0ZfQl9yYXRpbycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnIDE0LTE3IGMgYXRvbWVzIGZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnRmlybWljdXRlcy9CYWN0ZXJvaWRldGVzIHJhdGlvJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgpnZ3NjYXR0ZXIocGh5bHVtX1NULCB4PSdjMTQuMTcnLCB5PSdGX0JfcmF0aW8nLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICc+IDE0LTE3IGMgYXRvbWVzIGZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnRmlybWljdXRlcy9CYWN0ZXJvaWRldGVzIHJhdGlvJykrCiAgCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKZ2dzY2F0dGVyKHBoeWx1bV9TVCwgeD0nYzE4LjE5JywgeT0nRl9CX3JhdGlvJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICcgMTgtMTkgYyBhdG9tZXMgZmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdGaXJtaWN1dGVzL0JhY3Rlcm9pZGV0ZXMgcmF0aW8nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmdnc2NhdHRlcihwaHlsdW1fU1QsIHg9J2MxOC4xOScsIHk9J0ZfQl9yYXRpbycsICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJzE4LTE5IGMgYXRvbWVzIGZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnRmlybWljdXRlcy9CYWN0ZXJvaWRldGVzIHJhdGlvJykrCiAgCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKZ2dzY2F0dGVyKHBoeWx1bV9TVCwgeD0nYzIwLjIxJywgeT0nRl9CX3JhdGlvJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICcgMjAtMjEgYyBhdG9tZXMgZmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdGaXJtaWN1dGVzL0JhY3Rlcm9pZGV0ZXMgcmF0aW8nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmdnc2NhdHRlcihwaHlsdW1fU1QsIHg9J2MyMC4yMScsIHk9J0ZfQl9yYXRpbycsICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJzIwLTIxIGMgYXRvbWVzIGZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnRmlybWljdXRlcy9CYWN0ZXJvaWRldGVzIHJhdGlvJykrCiAgCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKZ2dzY2F0dGVyKHBoeWx1bV9TVCwgeD0nYzIyLjI0JywgeT0nRl9CX3JhdGlvJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICcgMjItMjQgYyBhdG9tZXMgZmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdGaXJtaWN1dGVzL0JhY3Rlcm9pZGV0ZXMgcmF0aW8nKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmdnc2NhdHRlcihwaHlsdW1fU1QsIHg9J2MyMC4yMScsIHk9J0ZfQl9yYXRpbycsICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJzIwLTIxIGMgYXRvbWVzIGZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnRmlybWljdXRlcy9CYWN0ZXJvaWRldGVzIHJhdGlvJykrCiAgCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKZ2dzY2F0dGVyKHBoeWx1bV9TVCwgeD0ndG90YWwnLCB5PSdGX0JfcmF0aW8nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJyB0b3RhbCBmYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ0Zpcm1pY3V0ZXMvQmFjdGVyb2lkZXRlcyByYXRpbycpKwogIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKZ2dzY2F0dGVyKHBoeWx1bV9TVCwgeD0ndG90YWwnLCB5PSdGX0JfcmF0aW8nLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICd0b3RhbCBmYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ0Zpcm1pY3V0ZXMvQmFjdGVyb2lkZXRlcyByYXRpbycpKwogIAogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmBgYAoKNS4yIEtvcnJlbGF0aW9uZW4gZ2Vzw6R0dGlndGUgRkEgdW5kIHVuZ2Vzw6R0dGlndGUgRkEgbWl0IHBoeWx1bS1sZXZlbAoKRmlsdGVybiBkZXIgUGh5bHVtLU1ldGFkYXRlbiwgaGluenVmw7xnZW4gdm9uIGxvZy1UcmFuc2Zvcm1hdGlvbiB1bmQgUHNldWRvY291bnQgMC4wMDAxCgpgYGB7cn0KCnBoeWx1bV9TVF9sb2cgPC0gcGh5bHVtX1NUWyxjKDM6OCldICsgMC4wMDAwMQoKcGh5bHVtX1NUX2xvZyA8LSBsb2cxMChwaHlsdW1fU1RfbG9nKQoKcGh5bHVtX1NUIDwtIGNiaW5kKHBoeWx1bV9TVF9sb2csIHBoeWx1bV9TVFssIGMoOTozMyldKQoKcGh5bHVtX2NvbG5hbWVzIDwtIGNvbG5hbWVzKHJlbGFiX3BoeWx1bV9zcHJlYWRbLCBjKDM6OCldKQoKCgpjb3JyX21hcF9waHlsdW1fdW5zYXQgPC0gZmlsdGVyKHBoeWx1bV9TVCwgIWlzLm5hKHVuc2F0KSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0IDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewoKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV91bnNhdCwgIWlzLm5hKGkpKQoKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkdW5zYXQKCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQoKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUuMSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZS4xID09ICJQUkUiKSkkdW5zYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUuMSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUuMSA9PSAiUE9TVCIpKSR1bnNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCgogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0KSsxCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXRbbnJvdywiRkEiXSA8LSAidW5zYXQiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXRbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0W25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXRbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXRbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0W25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXRbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXRbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdCRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0JHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkgCgpjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdCRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdCRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fdW5zYXQkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX3Vuc2F0JHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV91bnNhdCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy91bnNhdC5waHlsdW0udHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKCmBgYAoKUGxvdHRlbiBkZXIgS29ycmVsYXRpb25lbiB6d2lzY2hlbiBnZXPDpHR0aWd0ZW4gdW5kIHVuZ2Vzw6R0dGlndGVuIEZBIHVuZCBwaHlsdW0tbGV2ZWwKClRlaWx3ZWlzZSBpbiBBcmJlaXQKCmBgYHtyfQoKcGh5bHVtX1NUJGtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMKCm1lbHQuRmkgPC0gbWVsdChwaHlsdW1fU1QsIGlkLnZhcnMgPSBjKCdUaW1lLjEnLCAna19fQmFjdGVyaWEucF9fRmlybWljdXRlcycpLCBtZWFzdXJlLnZhcnMgPSBjKCdzYXQnLCAndW5zYXQnKSkKCm1lbHQuRmk8LWRwbHlyOjpyZW5hbWUobWVsdC5GaSwgRkE9dmFyaWFibGUpCm1lbHQuRmkgPC0gZHBseXI6OnJlbmFtZShtZWx0LkZpLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKbWVsdC5GaS5wciA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuRmksICFUaW1lLjEgPT0gJ1BPU1QnKSkKCm1lbHQuRmkucG8gPC0gc3Vic2V0KGZpbHRlcihtZWx0LkZpLCAhVGltZS4xID09ICdQUkUnKSkKCm1lbHQuRmkucHIka19fQmFjdGVyaWEucF9fRmlybWljdXRlcwoKZ2dzY2F0dGVyKG1lbHQuRmkucHIsIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nLCAnc3RlZWxibHVlMicsICdkZWVwcGluazInLCAnY3lhbicsJ3llbGxvdycpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDMwMCwgLTAuNyksY29yLmNvZWYuc2l6ZSA9IDYsIHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzJykrCiAgZmFjZXRfZ3JpZCgufiBGQSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1BSRScpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgpnZ3NjYXR0ZXIobWVsdC5GaS5wbywgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMnLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicsICdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicsICdjeWFuJywneWVsbG93JyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPSBjKDUwMCwgLTAuNzUpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzJykrCiAgZmFjZXRfZ3JpZCgufiBGQSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1BPU1QnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKZ2dzY2F0dGVyKG1lbHQuRmksIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nLCAnc3RlZWxibHVlMicsICdkZWVwcGluazInLCAnY3lhbicsJ3llbGxvdycpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYyg1MDAsIC0wLjcpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzJykrCiAgZmFjZXRfZ3JpZCgufiBGQSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1RpbWVzIHRvZ2V0aGVyJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCgoKCgpwaHlsdW1fU1Qka19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcwoKbWVsdC5CYSA8LSBtZWx0KHBoeWx1bV9TVCwgaWQudmFycyA9IGMoJ1RpbWUuMScsICdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzJyksIG1lYXN1cmUudmFycyA9IGMoJ3NhdCcsICd1bnNhdCcpKQoKbWVsdC5CYTwtZHBseXI6OnJlbmFtZShtZWx0LkJhLCBGQT12YXJpYWJsZSkKbWVsdC5CYSA8LSBkcGx5cjo6cmVuYW1lKG1lbHQuQmEsIENvbmNlbnRyYXRpb249dmFsdWUpCgptZWx0LkJhLnByIDwtIHN1YnNldChmaWx0ZXIobWVsdC5CYSwgIVRpbWUuMSA9PSAnUE9TVCcpKQoKbWVsdC5CYS5wbyA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuQmEsICFUaW1lLjEgPT0gJ1BSRScpKQoKZ2dzY2F0dGVyKG1lbHQuQmEucHIsIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nLCAnc3RlZWxibHVlMicsICdkZWVwcGluazInLCAnY3lhbicsJ3llbGxvdycpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDMwMCwgLTAuNyksY29yLmNvZWYuc2l6ZSA9IDYsIHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzJykrCiAgZmFjZXRfZ3JpZCgufiBGQSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQUkUnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKCmdnc2NhdHRlcihtZWx0LkJhLnBvLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJywgJ3N0ZWVsYmx1ZTInLCAnZGVlcHBpbmsyJywgJ2N5YW4nLCd5ZWxsb3cnKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoNTAwLCAtMC45NSksY29yLmNvZWYuc2l6ZSA9IDYseGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMnKSsKICBmYWNldF9ncmlkKC5+IEZBLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1BPU1QnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKZ2dzY2F0dGVyKG1lbHQuQmEsIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nLCAnc3RlZWxibHVlMicsICdkZWVwcGluazInLCAnY3lhbicsJ3llbGxvdycpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYyg1MDAsIC0wLjkpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzJykrCiAgZmFjZXRfZ3JpZCgufiBGQSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1RpbWVzIHRvZ2V0aGVyJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCnBoeWx1bV9TVCRUaW1lLjEgPC0gZmFjdG9yKHBoeWx1bV9TVCRUaW1lLjEsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIikpCgpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvdW5zYXQuYmFjdGVyb2lkZXRlcy5wZGYiLHdpZHRoPTgsIGhlaWdodD0xMCkKZ2dzY2F0dGVyKHBoeWx1bV9TVCwgeD0ndW5zYXQnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzJyxjb2xvciA9ICdUaW1lLjEnLCBwYWxldHRlID0gYygnc2t5Ymx1ZScsICdvcmNoaWQnKSwgIGFkZCA9ICdyZWcubGluZScsIGNvci5jb2VmLmNvb3JkID1jKDAsIC0wLjgpLGNvci5jb2VmLnNpemUgPSA3LGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnVW5nZXPDpHR0aWd0ZSBGZXR0c8OkdXJlbmtvbnplbnRyYXRpb25lbiBbbm1vbC9nXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlcyBWb3Jrb21tZW4gcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUuMSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKZGV2Lm9mZigpCgoKCgpwaHlsdW1fU1Qka19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhCgptZWx0LlZlIDwtIG1lbHQocGh5bHVtX1NULCBpZC52YXJzID0gYygnVGltZS4xJywgJ2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScpLCBtZWFzdXJlLnZhcnMgPSBjKCdzYXQnLCAndW5zYXQnKSkKCm1lbHQuVmU8LWRwbHlyOjpyZW5hbWUobWVsdC5WZSwgRkE9dmFyaWFibGUpCm1lbHQuVmUgPC0gZHBseXI6OnJlbmFtZShtZWx0LlZlLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKbWVsdC5WZS5wciA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuVmUsICFUaW1lLjEgPT0gJ1BPU1QnKSkKCm1lbHQuVmUucG8gPC0gc3Vic2V0KGZpbHRlcihtZWx0LlZlLCAhVGltZS4xID09ICdQUkUnKSkKCgpnZ3NjYXR0ZXIobWVsdC5WZS5wciwgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJywgJ3N0ZWVsYmx1ZTInLCAnZGVlcHBpbmsyJywgJ2N5YW4nLCd5ZWxsb3cnKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0wLjcpLGNvci5jb2VmLnNpemUgPSA2LCB4bGFiPSAnRmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVmVycnVjb21pY3JvYmlhJykrCiAgZmFjZXRfZ3JpZCgufiBGQSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1BSRScpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgpnZ3NjYXR0ZXIobWVsdC5WZS5wbywgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJywgJ3N0ZWVsYmx1ZTInLCAnZGVlcHBpbmsyJywgJ2N5YW4nLCd5ZWxsb3cnKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoNTAwLCAtMC4zKSxjb3IuY29lZi5zaXplID0gNix4bGFiPSAnRmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVmVycnVjb21pY3JvYmlhJykrCiAgZmFjZXRfZ3JpZCgufiBGQSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQT1NUJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LlZlLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nLCAnc3RlZWxibHVlMicsICdkZWVwcGluazInLCAnY3lhbicsJ3llbGxvdycpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0wLjUpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEnKSsKICBmYWNldF9ncmlkKC5+IEZBLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnVGltZXMgdG9nZXRoZXInKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKCgoKCnBoeWx1bV9TVCRrX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcwoKbWVsdC5UZSA8LSBtZWx0KHBoeWx1bV9TVCwgaWQudmFycyA9IGMoJ1RpbWUuMScsICdrX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcycpLCBtZWFzdXJlLnZhcnMgPSBjKCdzYXQnLCAndW5zYXQnKSkKCm1lbHQuVGU8LWRwbHlyOjpyZW5hbWUobWVsdC5UZSwgRkE9dmFyaWFibGUpCm1lbHQuVGUgPC0gZHBseXI6OnJlbmFtZShtZWx0LlRlLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKbWVsdC5UZS5wciA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuVGUsICFUaW1lLjEgPT0gJ1BPU1QnKSkKCm1lbHQuVGUucG8gPC0gc3Vic2V0KGZpbHRlcihtZWx0LlRlLCAhVGltZS4xID09ICdQUkUnKSkKCgpnZ3NjYXR0ZXIobWVsdC5UZS5wciwgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nLCAnc3RlZWxibHVlMicsICdkZWVwcGluazInLCAnY3lhbicsJ3llbGxvdycpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDM1MCwgLTEuMyksY29yLmNvZWYuc2l6ZSA9IDYsIHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcycpKwogIGZhY2V0X2dyaWQoLn4gRkEsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnUFJFJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCgpnZ3NjYXR0ZXIobWVsdC5UZS5wbywgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nLCAnc3RlZWxibHVlMicsICdkZWVwcGluazInLCAnY3lhbicsJ3llbGxvdycpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYyg2MDAsIC0xLjMpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcycpKwogIGZhY2V0X2dyaWQoLn4gRkEsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnUE9TVCcpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgpnZ3NjYXR0ZXIobWVsdC5UZSwgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nLCAnc3RlZWxibHVlMicsICdkZWVwcGluazInLCAnY3lhbicsJ3llbGxvdycpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0xLjUpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcycpKwogIGZhY2V0X2dyaWQoLn4gRkEsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdUaW1lcyB0b2dldGhlcicpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgoKCgoKcGh5bHVtX1NUJGtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhCgptZWx0LkFjIDwtIG1lbHQocGh5bHVtX1NULCBpZC52YXJzID0gYygnVGltZS4xJywgJ2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhJyksIG1lYXN1cmUudmFycyA9IGMoJ3NhdCcsICd1bnNhdCcpKQoKbWVsdC5BYzwtZHBseXI6OnJlbmFtZShtZWx0LkFjLCBGQT12YXJpYWJsZSkKbWVsdC5BYyA8LSBkcGx5cjo6cmVuYW1lKG1lbHQuQWMsIENvbmNlbnRyYXRpb249dmFsdWUpCnQKCm1lbHQuQWMucHIgPC0gc3Vic2V0KGZpbHRlcihtZWx0LkFjLCAhVGltZS4xID09ICdQT1NUJykpCgptZWx0LkFjLnBvIDwtIHN1YnNldChmaWx0ZXIobWVsdC5BYywgIVRpbWUuMSA9PSAnUFJFJykpCgpnZ3NjYXR0ZXIobWVsdC5BYy5wciwgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nLCAnc3RlZWxibHVlMicsICdkZWVwcGluazInLCAnY3lhbicsJ3llbGxvdycpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDMwMCwgLTEuMyksY29yLmNvZWYuc2l6ZSA9IDYsIHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYScpKwogIGZhY2V0X2dyaWQoLn4gRkEsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQUkUnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKCmdnc2NhdHRlcihtZWx0LkFjLnBvLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEnLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicsICdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicsICdjeWFuJywneWVsbG93JyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPSBjKDUwMCwgLTEuNCksY29yLmNvZWYuc2l6ZSA9IDYseGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhJykrCiAgZmFjZXRfZ3JpZCgufiBGQSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQT1NUJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LkFjLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEnLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicsICdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicsICdjeWFuJywneWVsbG93JyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPSBjKDMwMCwgLTEuMzUpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYScpKwogIGZhY2V0X2dyaWQoLn4gRkEsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnVGltZXMgdG9nZXRoZXInKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKCgoKcGh5bHVtX1NUJGtfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhCgptZWx0LlByIDwtIG1lbHQocGh5bHVtX1NULCBpZC52YXJzID0gYygnVGltZS4xJywgJ2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhJyksIG1lYXN1cmUudmFycyA9IGMoJ3NhdCcsICd1bnNhdCcpKQoKCm1lbHQuUHI8LWRwbHlyOjpyZW5hbWUobWVsdC5QciwgRkE9dmFyaWFibGUpCm1lbHQuUHIgPC0gZHBseXI6OnJlbmFtZShtZWx0LlByLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKbWVsdC5Qci5wciA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuUHIsICFUaW1lLjEgPT0gJ1BPU1QnKSkKCm1lbHQuUHIucG8gPC0gc3Vic2V0KGZpbHRlcihtZWx0LlByLCAhVGltZS4xID09ICdQUkUnKSkKCgpnZ3NjYXR0ZXIobWVsdC5Qci5wciwgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nLCAnc3RlZWxibHVlMicsICdkZWVwcGluazInLCAnY3lhbicsJ3llbGxvdycpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDMwMCwgLTEuNiksY29yLmNvZWYuc2l6ZSA9IDYsIHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYScpKwogIGZhY2V0X2dyaWQoLn4gRkEsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnUFJFJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LlByLnBvLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEnLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicsICdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicsICdjeWFuJywneWVsbG93JyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPSBjKDUwMCwgLTEuNiksY29yLmNvZWYuc2l6ZSA9IDYseGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhJykrCiAgZmFjZXRfZ3JpZCgufiBGQSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQT1NUJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LlByLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEnLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicsICdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicsICdjeWFuJywneWVsbG93JyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPSBjKDMwMCwgLTEuMzUpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYScpKwogIGZhY2V0X2dyaWQoLn4gRkEsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnVGltZXMgdG9nZXRoZXInKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKYGBgCgo1LjMgS29ycmVsYXRpb25lbiBnZXPDpHR0aWd0ZSBGQSB1bmQgdW5nZXPDpHR0aWd0ZSBGQSBtaXQgZ2VudXMtbGV2ZWwKCkZpbHRlcm4gZGVyIEdlbnVzLU1ldGFkYXRlbiwgaGluenVmw7xnZW4gdm9uIGxvZy1UcmFuc2Zvcm1hdGlvbiB1bmQgUHNldWRvY291bnQgMC4wMDAxCkxvb3AgR2VudXMtbGV2ZWwKCgpgYGB7cn0KCkZBX3N0b29sLlNUIDwtIG11dGF0ZShGQV9zdG9vbC5TVCwgU2FtcGxlSUQxID0gcGFzdGUoUHJvYmFuZCwgVGltZSwgc2VwID0gIi4iKSkKCnJvdy5uYW1lcyhGQV9zdG9vbC5TVCkgPC0gRkFfc3Rvb2wuU1QkU2FtcGxlSUQxCgpnZW51c19jb2xuYW1lcyA8LSBjb2xuYW1lcyhyZWxhYl9nZW51c19zcHJlYWRbLCBjKDM6MzEpXSkKCmNvbW1vbi5pZHMucmVsYWIgPC0gaW50ZXJzZWN0KHJvd25hbWVzKEZBX3N0b29sLlNUKSwgcm93bmFtZXMocmVsYWJfcGh5bHVtX0lEKSkKCkZBX3N0b29sLlNUIDwtIEZBX3N0b29sLlNUW2NvbW1vbi5pZHMucmVsYWIsXQoKcmVsYWJfcGh5bHVtX0lEIDwtIHJlbGFiX3BoeWx1bV9JRFtjb21tb24uaWRzLnJlbGFiLF0KCnJlbGFiX2dlbnVzX0lEIDwtIHJlbGFiX2dlbnVzX0lEW2NvbW1vbi5pZHMucmVsYWIsXQoKcmVsYWJfZ2VudXNfSURfbG9nIDwtIHJlbGFiX2dlbnVzX0lEWyxjKDM6MzEpXSArIDAuMDAwMDEKCnJlbGFiX2dlbnVzX0lEX2xvZyA8LSBsb2cxMChyZWxhYl9nZW51c19JRF9sb2cpCgpnZW51c19GQSA8LSBjYmluZChyZWxhYl9nZW51c19JRF9sb2csIEZBX3N0b29sLlNUKQoKCgpjb3JyX21hcF9nZW51c191bnNhdCA8LSBmaWx0ZXIoZ2VudXNfRkEsICFpcy5uYSh1bnNhdCkpCgpjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0IDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c191bnNhdCwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCR1bnNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSR1bnNhdAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkdW5zYXQKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfdW5zYXQpKzEKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0W25yb3csIkZBIl0gPSAidW5zYXR1cmF0ZWQiCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c191bnNhdFtucm93LCAiR2VudXMiXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0W25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c191bnNhdFtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0W25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0W25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9nZW51c191bnNhdFtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0W25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9nZW51c191bnNhdCRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfdW5zYXQkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9nZW51c191bnNhdCRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0JHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0JHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX3Vuc2F0JHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9nZW51c191bnNhdCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy91bnNhdC5nZW51cy50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gZGVyIEtvcnJlbGF0aW9uZW4gendpc2NoZW4gZ2Vzw6R0dGlndGVuIHVuZCB1bmdlc8OkdHRpZ3RlbiBGQSB1bmQgZ2VudXMtbGV2ZWwKClRlaWx3ZWlzZSBpbiBBcmJlaXQKCmBgYHtyfQoKZ2VudXNfRkEka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYQoKcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL3Vuc2F0Lm9zY2lsbG8ucGRmIix3aWR0aD04LCBoZWlnaHQ9MTApCmdnc2NhdHRlcihnZW51c19GQSwgeD0ndW5zYXQnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3NreWJsdWUnLCAnb3JjaGlkJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb3IuY29lZi5jb29yZCA9YygwLCAtMiksY29yLmNvZWYuc2l6ZSA9IDcsY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdVbmdlc8OkdHRpZ3RlIEZldHRzw6R1cmVua29uemVudHJhdGlvbmVuIFtubW9sL2ddJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmVzIFZvcmtvbW1lbiBnX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0wLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKZGV2Lm9mZgoKbWVsdC5PcyA8LSBtZWx0KGdlbnVzX0ZBLCBpZC52YXJzID0gYygnVGltZScsICdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyksIG1lYXN1cmUudmFycyA9IGMoJ3NhdCcsICd1bnNhdCcpKQptZWx0Lk9zPC1kcGx5cjo6cmVuYW1lKG1lbHQuT3MsIEZBPXZhcmlhYmxlKQptZWx0Lk9zIDwtIGRwbHlyOjpyZW5hbWUobWVsdC5PcywgQ29uY2VudHJhdGlvbj12YWx1ZSkKCm1lbHQuT3MucHIgPC0gc3Vic2V0KGZpbHRlcihtZWx0Lk9zLCAhVGltZSA9PSAnUE9TVCcpKQoKbWVsdC5Pcy5wbyA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuT3MsICFUaW1lID09ICdQUkUnKSkKCmdnc2NhdHRlcihtZWx0Lk9zLnByLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygnc3RlZWxibHVlMicsICdkZWVwcGluazInKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0yKSxjb3IuY29lZi5zaXplID0gNiwgeGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpKwogIGZhY2V0X2dyaWQoLn4gRkEsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQUkUnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKZ2dzY2F0dGVyKG1lbHQuT3MucG8sIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0yKSxjb3IuY29lZi5zaXplID0gNix4bGFiPSAnRmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgZmFjZXRfZ3JpZCgufiBGQSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQT1NUJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0Lk9zLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygnc3RlZWxibHVlMicsICdkZWVwcGluazInKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoMzAwLCAtMiksY29yLmNvZWYuc2l6ZSA9IDYseGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpKwogIGZhY2V0X2dyaWQoLn4gRkEsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdUaW1lcyB0b2dldGhlcicpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgoKCgoKCmdlbnVzX0ZBJGtfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0KCm1lbHQuQmkgPC0gbWVsdChnZW51c19GQSwgaWQudmFycyA9IGMoJ1RpbWUnLCAna19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bScpLCBtZWFzdXJlLnZhcnMgPSBjKCdzYXQnLCAndW5zYXQnKSkKCm1lbHQuQmk8LWRwbHlyOjpyZW5hbWUobWVsdC5CaSwgRkE9dmFyaWFibGUpCm1lbHQuQmkgPC0gZHBseXI6OnJlbmFtZShtZWx0LkJpLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKbWVsdC5CaS5wciA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuQmksICFUaW1lID09ICdQT1NUJykpCgptZWx0LkJpLnBvIDwtIHN1YnNldChmaWx0ZXIobWVsdC5CaSwgIVRpbWUgPT0gJ1BSRScpKQoKZ2dzY2F0dGVyKG1lbHQuQmkucHIsIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19BY3Rpbm9iYWN0ZXJpYS5vX19CaWZpZG9iYWN0ZXJpYWxlcy5mX19CaWZpZG9iYWN0ZXJpYWNlYWUuZ19fQmlmaWRvYmFjdGVyaXVtJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDMwMCwgLTEuMyksY29yLmNvZWYuc2l6ZSA9IDYsIHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBnX19CaWZpZG9iYWN0ZXJpdW0nKSsKICBmYWNldF9ncmlkKC5+IEZBLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnUFJFJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LkJpLnBvLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bScsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygnc3RlZWxibHVlMicsICdkZWVwcGluazInKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoMzAwLCAtMS41KSxjb3IuY29lZi5zaXplID0gNix4bGFiPSAnRmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmlmaWRvYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBGQSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQT1NUJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LkJpLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bScsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygnc3RlZWxibHVlMicsICdkZWVwcGluazInKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoMzAwLCAtMS4zKSxjb3IuY29lZi5zaXplID0gNix4bGFiPSAnRmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmlmaWRvYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBGQSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1RpbWVzIHRvZ2V0aGVyJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCgoKCgpnZW51c19GQSRrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19Db3Jpb2JhY3RlcmlpYS5vX19Db3Jpb2JhY3RlcmlhbGVzLmZfX0NvcmlvYmFjdGVyaWFjZWFlLmdfX0NvbGxpbnNlbGxhCgptZWx0LkNvIDwtIG1lbHQoZ2VudXNfRkEsIGlkLnZhcnMgPSBjKCdUaW1lJywgJ2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0NvcmlvYmFjdGVyaWlhLm9fX0NvcmlvYmFjdGVyaWFsZXMuZl9fQ29yaW9iYWN0ZXJpYWNlYWUuZ19fQ29sbGluc2VsbGEnKSwgbWVhc3VyZS52YXJzID0gYygnc2F0JywgJ3Vuc2F0JykpCgptZWx0LkNvPC1kcGx5cjo6cmVuYW1lKG1lbHQuQ28sIEZBPXZhcmlhYmxlKQptZWx0LkNvIDwtIGRwbHlyOjpyZW5hbWUobWVsdC5DbywgQ29uY2VudHJhdGlvbj12YWx1ZSkKCm1lbHQuQ28ucHIgPC0gc3Vic2V0KGZpbHRlcihtZWx0LkNvLCAhVGltZSA9PSAnUE9TVCcpKQoKbWVsdC5Dby5wbyA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuQ28sICFUaW1lID09ICdQUkUnKSkKCmdnc2NhdHRlcihtZWx0LkNvLnByLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQ29yaW9iYWN0ZXJpaWEub19fQ29yaW9iYWN0ZXJpYWxlcy5mX19Db3Jpb2JhY3RlcmlhY2VhZS5nX19Db2xsaW5zZWxsYScsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygnc3RlZWxibHVlMicsICdkZWVwcGluazInKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0xLjcpLGNvci5jb2VmLnNpemUgPSA2LCB4bGFiPSAnRmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29sbGluc2VsbGEnKSsKICBmYWNldF9ncmlkKC5+IEZBLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnUFJFJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LkNvLnBvLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQ29yaW9iYWN0ZXJpaWEub19fQ29yaW9iYWN0ZXJpYWxlcy5mX19Db3Jpb2JhY3RlcmlhY2VhZS5nX19Db2xsaW5zZWxsYScsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygnc3RlZWxibHVlMicsICdkZWVwcGluazInKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoMzAwLCAtMS41KSxjb3IuY29lZi5zaXplID0gNix4bGFiPSAnRmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29sbGluc2VsbGEnKSsKICBmYWNldF9ncmlkKC5+IEZBLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1BPU1QnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKZ2dzY2F0dGVyKG1lbHQuQ28sIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19Db3Jpb2JhY3RlcmlpYS5vX19Db3Jpb2JhY3RlcmlhbGVzLmZfX0NvcmlvYmFjdGVyaWFjZWFlLmdfX0NvbGxpbnNlbGxhJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0xLjUpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBnX19Db2xsaW5zZWxsYScpKwogIGZhY2V0X2dyaWQoLn4gRkEsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdUaW1lcyB0b2dldGhlcicpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgoKCgoKZ2VudXNfRkEka19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0KCm1lbHQuRmEgPC0gbWVsdChnZW51c19GQSwgaWQudmFycyA9IGMoJ1RpbWUnLCAna19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0nKSwgbWVhc3VyZS52YXJzID0gYygnc2F0JywgJ3Vuc2F0JykpCgptZWx0LkZhPC1kcGx5cjo6cmVuYW1lKG1lbHQuRmEsIEZBPXZhcmlhYmxlKQptZWx0LkZhIDwtIGRwbHlyOjpyZW5hbWUobWVsdC5GYSwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCm1lbHQuRmEucHIgPC0gc3Vic2V0KGZpbHRlcihtZWx0LkZhLCAhVGltZSA9PSAnUE9TVCcpKQoKbWVsdC5GYS5wbyA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuRmEsICFUaW1lID09ICdQUkUnKSkKCgpnZ3NjYXR0ZXIobWVsdC5GYS5wciwgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDMwMCwgLTEuMyksY29yLmNvZWYuc2l6ZSA9IDYsIHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBGQSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1BSRScpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgpnZ3NjYXR0ZXIobWVsdC5GYS5wbywgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0xLjUpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgZmFjZXRfZ3JpZCgufiBGQSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQT1NUJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LkZhLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0nLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3N0ZWVsYmx1ZTInLCAnZGVlcHBpbmsyJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPSBjKDMwMCwgLTEuNSksY29yLmNvZWYuc2l6ZSA9IDYseGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0nKSsKICBmYWNldF9ncmlkKC5+IEZBLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnVGltZXMgdG9nZXRoZXInKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKCgoKCgpnZW51c19GQSRrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYQoKbWVsdC5BayA8LSBtZWx0KGdlbnVzX0ZBLCBpZC52YXJzID0gYygnVGltZScsICdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYScpLCBtZWFzdXJlLnZhcnMgPSBjKCdzYXQnLCAndW5zYXQnKSkKCm1lbHQuQWs8LWRwbHlyOjpyZW5hbWUobWVsdC5BaywgRkE9dmFyaWFibGUpCm1lbHQuQWsgPC0gZHBseXI6OnJlbmFtZShtZWx0LkFrLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKbWVsdC5Bay5wciA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuQWssICFUaW1lID09ICdQT1NUJykpCgptZWx0LkFrLnBvIDwtIHN1YnNldChmaWx0ZXIobWVsdC5BaywgIVRpbWUgPT0gJ1BSRScpKQoKCmdnc2NhdHRlcihtZWx0LkFrLnByLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEnLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3N0ZWVsYmx1ZTInLCAnZGVlcHBpbmsyJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoMzAwLCAtMS4zKSxjb3IuY29lZi5zaXplID0gNiwgeGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0Fra2VybWFuc2lhJykrCiAgZmFjZXRfZ3JpZCgufiBGQSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1BSRScpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgpnZ3NjYXR0ZXIobWVsdC5Bay5wbywgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0wLjYpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBnX19Ba2tlcm1hbnNpYScpKwogIGZhY2V0X2dyaWQoLn4gRkEsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnUE9TVCcpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgpnZ3NjYXR0ZXIobWVsdC5BaywgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0wLjYpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBnX19Ba2tlcm1hbnNpYScpKwogIGZhY2V0X2dyaWQoLn4gRkEsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdUaW1lcyB0b2dldGhlcicpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgoKCgpnZW51c19GQSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQmxhdXRpYQoKbWVsdC5CbCA8LSBtZWx0KGdlbnVzX0ZBLCBpZC52YXJzID0gYygnVGltZScsICdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQmxhdXRpYScpLCBtZWFzdXJlLnZhcnMgPSBjKCdzYXQnLCAndW5zYXQnKSkKCm1lbHQuQmw8LWRwbHlyOjpyZW5hbWUobWVsdC5CbCwgRkE9dmFyaWFibGUpCm1lbHQuQmwgPC0gZHBseXI6OnJlbmFtZShtZWx0LkJsLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKbWVsdC5CbC5wciA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuQmwsICFUaW1lID09ICdQT1NUJykpCgptZWx0LkJsLnBvIDwtIHN1YnNldChmaWx0ZXIobWVsdC5CbCwgIVRpbWUgPT0gJ1BSRScpKQoKZ2dzY2F0dGVyKG1lbHQuQmwucHIsIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQmxhdXRpYScsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygnc3RlZWxibHVlMicsICdkZWVwcGluazInKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0xLjcpLGNvci5jb2VmLnNpemUgPSA2LCB4bGFiPSAnRmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmxhdXRpYScpKwogIGZhY2V0X2dyaWQoLn4gRkEsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQUkUnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKZ2dzY2F0dGVyKG1lbHQuQmwucG8sIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQmxhdXRpYScsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygnc3RlZWxibHVlMicsICdkZWVwcGluazInKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoMzAwLCAtMS42KSxjb3IuY29lZi5zaXplID0gNix4bGFiPSAnRmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmxhdXRpYScpKwogIGZhY2V0X2dyaWQoLn4gRkEsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnUE9TVCcpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgpnZ3NjYXR0ZXIobWVsdC5CbCwgeD0nQ29uY2VudHJhdGlvbicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19CbGF1dGlhJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0xLjYpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBnX19CbGF1dGlhJykrCiAgZmFjZXRfZ3JpZCgufiBGQSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1RpbWVzIHRvZ2V0aGVyJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCgoKCmdlbnVzX0ZBJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19CYWN0ZXJvaWRhY2VhZS5nX19CYWN0ZXJvaWRlcwoKbWVsdC5CYyA8LSBtZWx0KGdlbnVzX0ZBLCBpZC52YXJzID0gYygnVGltZScsICdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnKSwgbWVhc3VyZS52YXJzID0gYygnc2F0JywgJ3Vuc2F0JykpCgptZWx0LkJjPC1kcGx5cjo6cmVuYW1lKG1lbHQuQmMsIEZBPXZhcmlhYmxlKQptZWx0LkJjIDwtIGRwbHlyOjpyZW5hbWUobWVsdC5CYywgQ29uY2VudHJhdGlvbj12YWx1ZSkKCm1lbHQuQmMucHIgPC0gc3Vic2V0KGZpbHRlcihtZWx0LkJjLCAhVGltZSA9PSAnUE9TVCcpKQoKbWVsdC5CYy5wbyA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuQmMsICFUaW1lID09ICdQUkUnKSkKCmdnc2NhdHRlcihtZWx0LkJjLnByLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX0JhY3Rlcm9pZGFjZWFlLmdfX0JhY3Rlcm9pZGVzJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDIwMCwgLTAuOCksY29yLmNvZWYuc2l6ZSA9IDYsIHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBnX19CYWN0ZXJvaWRlcycpKwogIGZhY2V0X2dyaWQoLn4gRkEsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQUkUnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKZ2dzY2F0dGVyKG1lbHQuQmMucG8sIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3N0ZWVsYmx1ZTInLCAnZGVlcHBpbmsyJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPSBjKDMwMCwgLTEuMiksY29yLmNvZWYuc2l6ZSA9IDYseGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JhY3Rlcm9pZGVzJykrCiAgZmFjZXRfZ3JpZCgufiBGQSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQT1NUJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LkJjLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX0JhY3Rlcm9pZGFjZWFlLmdfX0JhY3Rlcm9pZGVzJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0xKSxjb3IuY29lZi5zaXplID0gNix4bGFiPSAnRmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmFjdGVyb2lkZXMnKSsKICBmYWNldF9ncmlkKC5+IEZBLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnVGltZXMgdG9nZXRoZXInKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKCgoKCmdlbnVzX0ZBJGtfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Db3Byb2NvY2N1cwoKbWVsdC5DcCA8LSBtZWx0KGdlbnVzX0ZBLCBpZC52YXJzID0gYygnVGltZScsICdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQ29wcm9jb2NjdXMnKSwgbWVhc3VyZS52YXJzID0gYygnc2F0JywgJ3Vuc2F0JykpCgptZWx0LkNwPC1kcGx5cjo6cmVuYW1lKG1lbHQuQ3AsIEZBPXZhcmlhYmxlKQptZWx0LkNwIDwtIGRwbHlyOjpyZW5hbWUobWVsdC5DcCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCm1lbHQuQ3AucHIgPC0gc3Vic2V0KGZpbHRlcihtZWx0LkNwLCAhVGltZSA9PSAnUE9TVCcpKQoKbWVsdC5DcC5wbyA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuQ3AsICFUaW1lID09ICdQUkUnKSkKCmdnc2NhdHRlcihtZWx0LkNwLnByLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDIwMCwgLTEuNiksY29yLmNvZWYuc2l6ZSA9IDYsIHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBnX19Db3Byb2NvY2N1cycpKwogIGZhY2V0X2dyaWQoLn4gRkEsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQUkUnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKZ2dzY2F0dGVyKG1lbHQuQ3AucG8sIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQ29wcm9jb2NjdXMnLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3N0ZWVsYmx1ZTInLCAnZGVlcHBpbmsyJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPSBjKDMwMCwgLTEuNSksY29yLmNvZWYuc2l6ZSA9IDYseGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBGQSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQT1NUJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LkNwLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0xLjUpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBnX19Db3Byb2NvY2N1cycpKwogIGZhY2V0X2dyaWQoLn4gRkEsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdUaW1lcyB0b2dldGhlcicpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgoKCgpnZW51c19GQSRrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fLlJ1bWlub2NvY2N1cy4KCm1lbHQuUnUgPC0gbWVsdChnZW51c19GQSwgaWQudmFycyA9IGMoJ1RpbWUnLCAna19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXy5SdW1pbm9jb2NjdXMuJyksIG1lYXN1cmUudmFycyA9IGMoJ3NhdCcsICd1bnNhdCcpKQoKbWVsdC5SdTwtZHBseXI6OnJlbmFtZShtZWx0LlJ1LCBGQT12YXJpYWJsZSkKbWVsdC5SdSA8LSBkcGx5cjo6cmVuYW1lKG1lbHQuUnUsIENvbmNlbnRyYXRpb249dmFsdWUpCgptZWx0LlJ1LnByIDwtIHN1YnNldChmaWx0ZXIobWVsdC5SdSwgIVRpbWUgPT0gJ1BPU1QnKSkKCm1lbHQuUnUucG8gPC0gc3Vic2V0KGZpbHRlcihtZWx0LlJ1LCAhVGltZSA9PSAnUFJFJykpCgoKZ2dzY2F0dGVyKG1lbHQuUnUucHIsIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fLlJ1bWlub2NvY2N1cy4nLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3N0ZWVsYmx1ZTInLCAnZGVlcHBpbmsyJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoMjAwLCAtMiksY29yLmNvZWYuc2l6ZSA9IDYsIHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBnX19SdW1pbm9jb2NjdXMnKSsKICBmYWNldF9ncmlkKC5+IEZBLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnUFJFJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LlJ1LnBvLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXy5SdW1pbm9jb2NjdXMuJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0yKSxjb3IuY29lZi5zaXplID0gNix4bGFiPSAnRmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUnVtaW5vY29jY3VzJykrCiAgZmFjZXRfZ3JpZCgufiBGQSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdQT1NUJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LlJ1LCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXy5SdW1pbm9jb2NjdXMuJyxjb2xvciA9ICdGQScsIHBhbGV0dGUgPSBjKCdzdGVlbGJsdWUyJywgJ2RlZXBwaW5rMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMDAsIC0xLjkpLGNvci5jb2VmLnNpemUgPSA2LHhsYWI9ICdGYXR0eSBhY2lkIGNvbmNlbnRyYXRpb24gW25tb2wvZ10nLCB5bGFiID0gJ1JlbGF0aXZlIEFidW5kYW5jZSBnX19SdW1pbm9jb2NjdXMnKSsKICBmYWNldF9ncmlkKC5+IEZBLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnVGltZXMgdG9nZXRoZXInKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKCgoKCmdlbnVzX0ZBJGtfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19QcmV2b3RlbGxhY2VhZS5nX19QcmV2b3RlbGxhCgptZWx0LlBlIDwtIG1lbHQoZ2VudXNfRkEsIGlkLnZhcnMgPSBjKCdUaW1lJywgJ2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19QcmV2b3RlbGxhY2VhZS5nX19QcmV2b3RlbGxhJyksIG1lYXN1cmUudmFycyA9IGMoJ3NhdCcsICd1bnNhdCcpKQoKCm1lbHQuUGU8LWRwbHlyOjpyZW5hbWUobWVsdC5QZSwgRkE9dmFyaWFibGUpCm1lbHQuUGUgPC0gZHBseXI6OnJlbmFtZShtZWx0LlBlLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKbWVsdC5QZS5wciA8LSBzdWJzZXQoZmlsdGVyKG1lbHQuUGUsICFUaW1lID09ICdQT1NUJykpCgptZWx0LlBlLnBvIDwtIHN1YnNldChmaWx0ZXIobWVsdC5QZSwgIVRpbWUgPT0gJ1BSRScpKQoKCmdnc2NhdHRlcihtZWx0LlBlLnByLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX1ByZXZvdGVsbGFjZWFlLmdfX1ByZXZvdGVsbGEnLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3N0ZWVsYmx1ZTInLCAnZGVlcHBpbmsyJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoMjAwLCAtMC42KSxjb3IuY29lZi5zaXplID0gNiwgeGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1ByZXZvdGVsbGEnKSsKICBmYWNldF9ncmlkKC5+IEZBLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2d0aXRsZSgnUFJFJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBzaXplPTE0KSkKCmdnc2NhdHRlcihtZWx0LlBlLnBvLCB4PSdDb25jZW50cmF0aW9uJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX1ByZXZvdGVsbGFjZWFlLmdfX1ByZXZvdGVsbGEnLGNvbG9yID0gJ0ZBJywgcGFsZXR0ZSA9IGMoJ3N0ZWVsYmx1ZTInLCAnZGVlcHBpbmsyJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPSBjKDMwMCwgLTAuNiksY29yLmNvZWYuc2l6ZSA9IDYseGxhYj0gJ0ZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScsIHlsYWIgPSAnUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1ByZXZvdGVsbGEnKSsKICBmYWNldF9ncmlkKC5+IEZBLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoJ1BPU1QnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIHNpemU9MTQpKQoKZ2dzY2F0dGVyKG1lbHQuUGUsIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fUHJldm90ZWxsYWNlYWUuZ19fUHJldm90ZWxsYScsY29sb3IgPSAnRkEnLCBwYWxldHRlID0gYygnc3RlZWxibHVlMicsICdkZWVwcGluazInKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoMzAwLCAtMC42KSxjb3IuY29lZi5zaXplID0gNix4bGFiPSAnRmF0dHkgYWNpZCBjb25jZW50cmF0aW9uIFtubW9sL2ddJywgeWxhYiA9ICdSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUHJldm90ZWxsYScpKwogIGZhY2V0X2dyaWQoLn4gRkEsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICBnZ3RpdGxlKCdUaW1lcyB0b2dldGhlcicpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZT0xNCkpCgpgYGAKCjYuIFNlcnVtbGlwaWRhbmFseXNlCgpMYWRlbiBkZXIgRGF0ZW4gdW5kIHRlc3RlbiBhdWYgTm9ybWFsdmVydGVpbHVuZwoKYGBge3J9CgpMSV9zZXJ1bSA8LSByZWFkLnRhYmxlKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMgemFobGVuLjEtMi50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLGhlYWQ9VCkKCkxJX3NlcnVtJFRpbWUgPC1mYWN0b3IoTElfc2VydW0kVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCnJvdy5uYW1lcyhMSV9zZXJ1bSkgPC0gTElfc2VydW0kU2FtcGxlSUQgICAgICAgICAgICAgICAgICAgICAgIAoKbmQuTEk8LSBkYXRhX2ZyYW1lKCkKCmZvciAoaSBpbiBMSV9jb2xuYW1lcykgIHsKICBmaXQgPC0gc2hhcGlyby50ZXN0KGFzLm1hdHJpeChhcy5kYXRhLmZyYW1lKGxhcHBseShMSV9zZXJ1bVssaV0sYXMubnVtZXJpYykpKSkKICBwID0gZml0JHAudmFsdWUKICBucm93ID0gbnJvdyhuZC5MSSkrMQogIG5kLkxJW25yb3csICJjb2x1bW4iXSA9IGkKICBuZC5MSVtucm93LCAicC52YWx1ZSJdID0gcm91bmQocCwgNCkKfQoKCmdncXFwbG90KExJX3NlcnVtJFN1bSwgeWxhYiA9ICJTdW0gc2VydW0gbGlwaWRzIFtubW9sL21sXSIsIHhsYWIgPSAiU2FtcGxlSUQiKQpnZ3FxcGxvdChMSV9zZXJ1bSRQRSwgeWxhYiA9ICJQaG9zcGhhdGlkeWxldGhhbm9sYW1pbmUKIHNlcnVtIGxpcGlkcyBbbm1vbC9tbF0iLCB4bGFiID0gIlNhbXBsZUlEIikKCmBgYAoKQWxsZSBQcm9iYW5kZW4gemVpZ2VuIFBSRSB1bmQgUE9TVCBQcm9iZW4sIEZvbGxvdy11cCBuaWNodCB2b3JoYW5kZW4KCkxvb3AgZsO8ciBXaWxjb3hvbi1UZXN0IHp3aXNjaGVuZCBkZW4gWmVpdHB1bmt0ZW4gUFJFIHVuZCBQT1NUCgpgYGB7cn0KCndpbGNveF9MSTwtIGRhdGFfZnJhbWUoKQoKZm9yIChpIGluIExJX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIExJX3NlcnVtICU+JSBkcm9wX25hKGkpIAogIAogIHggPC0gYXMubWF0cml4KGFzLmRhdGEuZnJhbWUobGFwcGx5KHRtcFssaV0sIGFzLm51bWVyaWMpKSkKICAKICB5IDwtIExJX3NlcnVtJFRpbWUgCiAgCiAgdG1wX3dpbGNveCA8LSBwYWlyd2lzZS53aWxjb3gudGVzdCh4LCB5LCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBUKQogIAogIHAgPC0gdG1wX3dpbGNveCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3cod2lsY294X0xJKSsxCiAgCiAgd2lsY294X0xJW25yb3csICJMSSJdIDwtIGkgCiAgCiAgCiAgd2lsY294X0xJW25yb3csICJNZWFuIFBSRSJdIDwtcm91bmQobWVhbihzdWJzZXQoZmlsdGVyKExJX3NlcnVtLFRpbWUgPT0gIlBSRSIpWyxpXSwhaXMubmEoaSksbmEucm0gPSBUUlVFKSwgMiwgbWVhbiwgIG5hLnJtID0gVFJVRSksIDQpCiAgCiAgd2lsY294X0xJW25yb3csICJzZCBQUkUiXSA8LXJvdW5kKHNkKGMoc3Vic2V0KGZpbHRlcihMSV9zZXJ1bSxUaW1lID09ICJQUkUiKVssaV0sIWlzLm5hKGkpLG5hLnJtID0gVFJVRSksIG5hLnJtID0gVFJVRSkpLCA0KQogIAogIHdpbGNveF9MSVtucm93LCAiTWVhbiBQT1NUIl0gPC1yb3VuZChtZWFuKHN1YnNldChmaWx0ZXIoTElfc2VydW0sVGltZSA9PSAiUE9TVCIpWyxpXSwhaXMubmEoaSksIG5hLnJtID0gVFJVRSksIDIsIG1lYW4sICBuYS5ybSA9IFRSVUUpLCA0KQogIAogIHdpbGNveF9MSVtucm93LCAic2QgUE9TVCJdIDwtIHJvdW5kKHNkKGMoc3Vic2V0KGZpbHRlcihMSV9zZXJ1bSxUaW1lID09ICJQT1NUIilbLGldLCFpcy5uYShpKSwgbmEucm0gPSBUUlVFKSxuYS5ybSA9IFRSVUUpKSwgNCkKICAKICB3aWxjb3hfTElbbnJvdywgInAudmFsdWUiXSA8LSByb3VuZChwLCA0KSB9CgoKd3JpdGUudGFibGUod2lsY294X0xJLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcy9UYWJlbGxlbi9MSS5wcmUucG9zdC50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKClBsb3R0ZW4gZGVyIFNlcnVtbGlwaWRlIHp1IGRlbiBaZWl0cHVua3RlbiBQUkUgdW5kIFBPU1QKSW4gQXJiZWl0LCB1bnRlcnRlaWx0IGluIEd5bGNlcm9waG9zcGhvbGlwaWRlIHVuZCBTcGhpbmdvbGlwaWRlCgpgYGB7cn0KTElfc2VydW0ubWVsdDIgPC0gbWVsdChMSV9zZXJ1bSwgaWQudmFycyA9ICdUaW1lJywgbWVhc3VyZS52YXJzID0gYygnUEMnLCAnUENPJywgJ1BFJywgJ1BJJywnUEVQJywgJ0xQQycpKQpMSV9zZXJ1bS5tZWx0MiA8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQyLCBMST12YXJpYWJsZSkKTElfc2VydW0ubWVsdDIgPC0gZHBseXI6OnJlbmFtZShMSV9zZXJ1bS5tZWx0MiwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCnBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9TTC5LRC5wZGYiLHdpZHRoPTksIGhlaWdodD0xMCkKZ2dwbG90KExJX3NlcnVtLm1lbHQyLGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gTEkpKSArCiAgeGxhYiAoJ1plaXRwdW5rdCcpICsgeWxhYiAoJ0tvbnplbnRyYXRpb24gW25tb2wvbWxdJykgKyAKICBnZW9tX2JveHBsb3Qod2lkdGggPSAuNywgbHdkPTAuNikrIHRoZW1lX2NsYXNzaWMoKSsKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJQaG9zcGhhdGlkeWxjaG9saW5lIiwgIlBDTyIsICJQaG9zcGhhdGlkeWxldGhhbm9sYW1pbmUiLCAiUGhvc3BoYXRpZHlsaW5vc2l0b2wiLCAiUEUgYmFzZWQgcGxhc21hbG9nZW5zIiwgIkx5c29waG9zcGhhdGlkeWxjaG9saW5lIiksCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygiIzk4MDA0MyIsICIjZGQxYzc3IiwgIiNkZjY1YjAiLCAiI2M5OTRjNyIsICIjZDRiOWRhIiwgIiNmMWVlZjYiKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYyggIlBPU1QiKSkpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNikpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKZGV2Lm9mZigpCgoKCkxJX3NlcnVtLm1lbHQxIDwtIG1lbHQoTElfc2VydW0sIGlkLnZhcnMgPSAnVGltZScsIG1lYXN1cmUudmFycyA9IGMoJ1NNJywnQ0VSJykpCkxJX3NlcnVtLm1lbHQxIDwtIGRwbHlyOjpyZW5hbWUoTElfc2VydW0ubWVsdDEsIExJPXZhcmlhYmxlKQpMSV9zZXJ1bS5tZWx0MSA8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQxLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL1NMMi5LRC5wZGYiLHdpZHRoPTgsIGhlaWdodD0xMCkKZ2dwbG90KExJX3NlcnVtLm1lbHQxLGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gTEkpKSArCiAgeGxhYiAoJ1plaXRwdW5rdCcpICsgeWxhYiAoJ0tvbnplbnRyYXRpb24gW25tb2wvbWxdJykgKyAKICBnZW9tX2JveHBsb3Qod2lkdGggPSAuMywgbHdkPTAuOCkrIHRoZW1lX2NsYXNzaWMoKSsKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJTcGhpbmdvbXllbGluIiwgIkNlcmFtaWRlIiksCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygiI2ZhOWZiNSIsICIjZmRlMGRkIikpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoICJQT1NUIikpKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSxheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTYpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpKwogIGV4cGFuZF9saW1pdHMoeT1jKDAsIDIzMDApKQpkZXYub2ZmKCkKYGBgCgpBbGxlIFNlcnVtbGlwaWRlIHp1c2FtbWVuLCBQcm96ZW50dWFsZSBWZXJ0ZWlsdW5nCgpgYGB7cn0KCkxJX3NlcnVtLm1lbHQgPC0gbWVsdChMSV9zZXJ1bSwgaWQudmFycyA9ICdUaW1lJywgbWVhc3VyZS52YXJzID0gYygnUEMnLCAnUENPJywnU00nLCAnUEUnLCAnUEknLCdQRVAnLCAnTFBDJywnQ0VSJykpCgpMSV9zZXJ1bS5tZWx0IDwtIGRwbHlyOjpyZW5hbWUoTElfc2VydW0ubWVsdCwgTEk9dmFyaWFibGUpCkxJX3NlcnVtLm1lbHQgPC0gZHBseXI6OnJlbmFtZShMSV9zZXJ1bS5tZWx0LCBDb25jZW50cmF0aW9uPXZhbHVlKQoKcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL1NlcnVtbGlwaWRzLmFsbHRpbWVzLnBkZiIsd2lkdGg9OSwgaGVpZ2h0PTEwKQpnZ3Bsb3QoTElfc2VydW0ubWVsdCxhZXMoeD1MSSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBMSSkpICsKICB4bGFiICgnU2VydW1saXBpZCcpICsgeWxhYiAoJ0tvbnplbnRyYXRpb24gW25tb2wvbWxdJykgKyAKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJQQyIgPSAiUGhvc3BoYXRpZHlsY2hvbGluZSIsICJQQ08iID0gIlBob3NwaGF0aWR5bGNob2xpbmUgUGxhc21vZ2VuIiwgIlNNIiA9ICJTcGhpbmdvbXllbGluIiwgIlBFIiA9ICJQaG9zcGhhdGlkeWxldGhhbm9sYW1pbmUiLCAiUEkiID0gIlBob3NwaGF0aWR5bGlub3NpdG9sIiwgIlBFUCIgPSAiUGhvc3BoYXRpZHlsZXRoYW5vbGFtaW4gUGxhc21hbG9nZW4iLCAiTFBDIiA9ICJMeXNvcGhvc3BoYXRpZHlsY2hvbGluZSIsICJDRVIiID0iQ2VyYW1pZCIpKSsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAuNSwgbHdkPTAuNSkgKyB0aGVtZV9jbGFzc2ljKCkrCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygiUGhvc3BoYXRpZHlsY2hvbGluZSIsICJQaG9zcGhhdGlkeWxjaG9saW5lIHBsYXNtb2dlbiIsICJTcGhpbmdvbXllbGluIiwgIlBob3NwaGF0aWR5bGV0aGFub2xhbWluZSIsICJQaG9zcGhhdGlkeWxpbm9zaXRvbCIsICJQRSBiYXNlZCBwbGFzbWFsb2dlbnMiLCAiTHlzb3Bob3NwaGF0aWR5bGNob2xpbmUiLCAiQ2VyYW1pZGUiKSwKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCIjZGY2NWIwIiwgIiNkZjY1YjAiLCAiI2ZhOWZiNSIsICIjZGY2NWIwIiwgIiNkZjY1YjAiLCAiI2RmNjViMCIsICIjZGY2NWIwIiwgIiNmYTlmYjUiKSkgKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTI1LCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQpkZXYub2ZmKCkKCgpMSV9zZXJ1bS5zdW0ubWVsdCA8LSBtZWx0KExJX3NlcnVtLCBpZC52YXJzID0gJ1RpbWUnLCBtZWFzdXJlLnZhcnMgPSBjKCdTdW0nLCAnU3VtLk1lbWJyYW5lJywnU3VtLlN0b3JhZ2UnLCAnU3VtLkx5c28nKSkKTElfc2VydW0uc3VtLm1lbHQgPC0gcmVuYW1lKExJX3NlcnVtLnN1bS5tZWx0LCBMST12YXJpYWJsZSkKTElfc2VydW0uc3VtLm1lbHQgPC0gcmVuYW1lKExJX3NlcnVtLnN1bS5tZWx0LCBDb25jZW50cmF0aW9uPXZhbHVlKQoKZ2dwbG90KExJX3NlcnVtLnN1bS5tZWx0LGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gTEkpKSArCiAgeGxhYiAoJ1RpbWUgUG9pbnQnKSArIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXScpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJTdW1tYXJ5IHRvdGFsIiwgIlN1bW1hcnkgTWVtYnJhbmUiLCAiU3VtbWFyeSBTdG9yYWdlIiwgIlN1bW1hcnkgTHlzbyIpLAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoInRvbWF0byIsICJ5ZWxsb3dncmVlbiIsICJzdGVlbGJsdWUyIiwgIm9yY2hpZDIiKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCgpMSV9zZXJ1bS5wLm1lbHQgPC0gbWVsdChMSV9zZXJ1bSwgaWQudmFycyA9ICdUaW1lJywgbWVhc3VyZS52YXJzID0gYyggJ1AuTWVtYnJhbmUnLCdQLlN0b3JhZ2UnLCAnUC5MeXNvJykpCkxJX3NlcnVtLnAubWVsdCA8LSByZW5hbWUoTElfc2VydW0ucC5tZWx0LCBMST12YXJpYWJsZSkKTElfc2VydW0ucC5tZWx0IDwtIHJlbmFtZShMSV9zZXJ1bS5wLm1lbHQsIENvbmNlbnRyYXRpb249dmFsdWUpCgpnZ3Bsb3QoTElfc2VydW0ucC5tZWx0LGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gTEkpKSArCiAgeGxhYiAoJ1RpbWUgUG9pbnQnKSArIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXScpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCAiUGVyY2VudGFnZSBNZW1icmFuZSIsICJQZXJjZW50YWdlIFN0b3JhZ2UiLCAiUGVyY2VudGFnZSBMeXNvIiksCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygieWVsbG93Z3JlZW4iLCAic3RlZWxibHVlMiIsICJvcmNoaWQyIikpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpgYGAKClBsb3R0ZW4gZGVyIGVpbnplbG5lbiBTZXJ1bWxpcGlkZSwgbGlua2VkIGJ5IFByb2JhbmQKCmBgYHtyfQpnZ3BhaXJlZChMSV9zZXJ1bSwgeD0nVGltZScsIHk9J1N1bScsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFKSArCiAgeGxhYignVGltZXBvaW50JykgKyB5bGFiKCdDb25jZW50cmF0aW9uIFN1bW1hcnkgc2VydW0gbGlwaWRzIFtubW9sL21sXScpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3BhaXJlZChMSV9zZXJ1bSwgeD0nVGltZScsIHk9J1BDJywgY29sb3IgPSAnYmxhY2snLCBmaWxsID0gJ1RpbWUnLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdQQyBzZXJ1bSBsaXBpZHMgW25tb2wvbWxdJykgKyB5bGFiKCdDb25jZW50cmF0aW9uJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdncGFpcmVkKExJX3NlcnVtLCB4PSdUaW1lJywgeT0nUENPJywgY29sb3IgPSAnYmxhY2snLCBmaWxsID0gJ1RpbWUnLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdQQ08gc2VydW0gbGlwaWRzIFtubW9sL21sXScpICsgeWxhYignQ29uY2VudHJhdGlvbicpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3BhaXJlZChMSV9zZXJ1bSwgeD0nVGltZScsIHk9J1NNJywgY29sb3IgPSAnYmxhY2snLCBmaWxsID0gJ1RpbWUnLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdTTSBzZXJ1bSBsaXBpZHMgW25tb2wvbWxdJykgKyB5bGFiKCdDb25jZW50cmF0aW9uJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCnRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3BhaXJlZChMSV9zZXJ1bSwgeD0nVGltZScsIHk9J0xQQycsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFKSArCiAgeGxhYignVGltZXBvaW50JykgKyB5bGFiKCdMUEMgc2VydW0gbGlwaWRzIENvbmNlbnRyYXRpb24gW25tb2wvbWxdJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdncGFpcmVkKExJX3NlcnVtLCB4PSdUaW1lJywgeT0nUEknLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywnd2hpdGVzbW9rZScpLCBsaW5lLmNvbG9yID0gJ2dyZXk2MCcsIGxpbmUuc2l6ZSA9IDAuNCwgZ3JvdXAgPSAnUHJvYmFuZCcsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ1BJIHNlcnVtIGxpcGlkcyBbbm1vbC9tbF0nKSArIHlsYWIoJ0NvbmNlbnRyYXRpb24nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dwYWlyZWQoTElfc2VydW0sIHg9J1RpbWUnLCB5PSdQRVAnLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywnd2hpdGVzbW9rZScpLCBsaW5lLmNvbG9yID0gJ2dyZXk2MCcsIGxpbmUuc2l6ZSA9IDAuNCwgZ3JvdXAgPSAnUHJvYmFuZCcsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ1BFUCBzZXJ1bSBsaXBpZHMgW25tb2wvbWxdJykgKyB5bGFiKCdDb25jZW50cmF0aW9uJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdncGFpcmVkKExJX3NlcnVtLCB4PSdUaW1lJywgeT0nTFBDJywgY29sb3IgPSAnYmxhY2snLCBmaWxsID0gJ1RpbWUnLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdMUEMgc2VydW0gbGlwaWRzIFtubW9sL21sXScpICsgeWxhYignQ29uY2VudHJhdGlvbicpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3BhaXJlZChMSV9zZXJ1bSwgeD0nVGltZScsIHk9J0NFUicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFKSArCiAgeGxhYignVGltZXBvaW50JykgKyB5bGFiKCdDRVIgc2VydW0gbGlwaWRzIENvbmNlbnRyYXRpb25bbm1vbC9tbF0nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dwYWlyZWQoTElfc2VydW0sIHg9J1RpbWUnLCB5PSdDRVInLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywnd2hpdGVzbW9rZScpLCBsaW5lLmNvbG9yID0gJ2dyZXk2MCcsIGxpbmUuc2l6ZSA9IDAuNCwgZ3JvdXAgPSAnUHJvYmFuZCcsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ0NFUiBzZXJ1bSBsaXBpZHMgW25tb2wvbWxdJykgKyB5bGFiKCdDb25jZW50cmF0aW9uJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9VGltZSksIGFscGhhPTAuNSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLnNpemU9NCwgb3V0bGllci5jb2xvdXI9J2JsdWUnLCBhbHBoYT0wLjUpCgpnZ3BhaXJlZChMSV9zZXJ1bSwgeD0nVGltZScsIHk9J0hleENlcicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFKSArCiAgeGxhYignVGltZXBvaW50JykgKyB5bGFiKCdIZXhDZXIgc2VydW0gbGlwaWRzIENvbmNlbnRyYXRpb24gW25tb2wvbWxdJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdncGFpcmVkKExJX3NlcnVtLCB4PSdUaW1lJywgeT0nU3VtLk1lbWJyYW5lJywgY29sb3IgPSAnYmxhY2snLCBmaWxsID0gJ1RpbWUnLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdNZW1icmFuZSBzZXJ1bSBsaXBpZHMgW25tb2wvbWxdJykgKyB5bGFiKCdDb25jZW50cmF0aW9uJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdncGFpcmVkKExJX3NlcnVtLCB4PSdUaW1lJywgeT0nU3VtLlN0b3JhZ2UnLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywnd2hpdGVzbW9rZScpLCBsaW5lLmNvbG9yID0gJ2dyZXk2MCcsIGxpbmUuc2l6ZSA9IDAuNCwgZ3JvdXAgPSAnUHJvYmFuZCcsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ1N0b3JhZ2Ugc2VydW0gbGlwaWRzIFtubW9sL21sXScpICsgeWxhYignQ29uY2VudHJhdGlvbicpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3BhaXJlZChMSV9zZXJ1bSwgeD0nVGltZScsIHk9J1N1bS5MeXNvJywgY29sb3IgPSAnYmxhY2snLCBmaWxsID0gJ1RpbWUnLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdMeXNvIHNlcnVtIGxpcGlkcyBbbm1vbC9tbF0nKSArIHlsYWIoJ0NvbmNlbnRyYXRpb24nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dwYWlyZWQoTElfc2VydW0sIHg9J1RpbWUnLCB5PSdQLk1lbWJyYW5lJywgY29sb3IgPSAnYmxhY2snLCBmaWxsID0gJ1RpbWUnLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdNZW1icmFuZSBzZXJ1bSBsaXBpZHMgWyVdJykgKyB5bGFiKCdDb25jZW50cmF0aW9uJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdncGFpcmVkKExJX3NlcnVtLCB4PSdUaW1lJywgeT0nTFBDLlBDJywgY29sb3IgPSAnYmxhY2snLCBmaWxsID0gJ1RpbWUnLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdMUEMvUEMgc2VydW0gbGlwaWQgcmF0aW8nKSArIHlsYWIoJ0NvbmNlbnRyYXRpb24nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dwYWlyZWQoTElfc2VydW0sIHg9J1RpbWUnLCB5PSdDRVIuU00nLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywnd2hpdGVzbW9rZScpLCBsaW5lLmNvbG9yID0gJ2dyZXk2MCcsIGxpbmUuc2l6ZSA9IDAuNCwgZ3JvdXAgPSAnUHJvYmFuZCcsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ0Nlci9TTSBzZXJ1bSBsaXBpZCByYXRpbycpICsgeWxhYignQ29uY2VudHJhdGlvbicpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3BhaXJlZChMSV9zZXJ1bSwgeD0nVGltZScsIHk9J0hleENlci5DRVInLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywnd2hpdGVzbW9rZScpLCBsaW5lLmNvbG9yID0gJ2dyZXk2MCcsIGxpbmUuc2l6ZSA9IDAuNCwgZ3JvdXAgPSAnUHJvYmFuZCcsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ0hleENlci9DZXIgc2VydW0gbGlwaWQgcmF0aW8nKSArIHlsYWIoJ0NvbmNlbnRyYXRpb24nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dwYWlyZWQoTElfc2VydW0sIHg9J1RpbWUnLCB5PSdQQy5QRScsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFKSArCiAgeGxhYignUEMvUEUgc2VydW0gbGlwaWQgcmF0aW8nKSArIHlsYWIoJ0NvbmNlbnRyYXRpb24nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKYGBgCgpLb3JyZWxhdGlvbmVuIHp3aXNjaGVuIGVpbnplbG5lbiBTZXJ1bWxpcGlkZW4sIGxpbmtlZCBieSBQcm9iYW5kcwoKYGBge3J9CkxJX3NlcnVtLm1lbHQxIDwtIG1lbHQoTElfc2VydW0sIGlkLnZhcnMgPSBjKCdUaW1lJywnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdQQycsICdMUEMnKSkKTElfc2VydW0ubWVsdDEgPC0gZHBseXI6OnJlbmFtZShMSV9zZXJ1bS5tZWx0MSwgTEk9dmFyaWFibGUpCkxJX3NlcnVtLm1lbHQxIDwtIGRwbHlyOjpyZW5hbWUoTElfc2VydW0ubWVsdDEsIENvbmNlbnRyYXRpb249dmFsdWUpCgpMSV9zZXJ1bS5tZWx0MSRUaW1lIDwtIGZhY3RvcihMSV9zZXJ1bS5tZWx0MSRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKZ2dwYWlyZWQoTElfc2VydW0ubWVsdDEsIHg9J0xJJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgZmFjZXQuYnkgPSAnVGltZScsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ1BDIGFuZCBMUEMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nKSArIHlsYWIoJ0NvbmNlbnRyYXRpb24nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKQoKCgoKTElfc2VydW0ubWVsdDIgPC0gbWVsdChMSV9zZXJ1bSwgaWQudmFycyA9IGMoJ1RpbWUnLCdQcm9iYW5kJyksIG1lYXN1cmUudmFycyA9IGMoJ1N1bS5TdG9yYWdlJywgJ1N1bS5NZW1icmFuZScpKQpMSV9zZXJ1bS5tZWx0MiA8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQyLCBMST12YXJpYWJsZSkKTElfc2VydW0ubWVsdDIgPC0gZHBseXI6OnJlbmFtZShMSV9zZXJ1bS5tZWx0MiwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCkxJX3NlcnVtLm1lbHQyJFRpbWUgPC0gZmFjdG9yKExJX3NlcnVtLm1lbHQyJFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIikpCgpnZ3BhaXJlZChMSV9zZXJ1bS5tZWx0MiwgeD0nTEknLCB5PSdDb25jZW50cmF0aW9uJywgY29sb3IgPSAnYmxhY2snLCBmaWxsID0gJ1RpbWUnLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBmYWNldC5ieSA9ICdUaW1lJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFKSArCiAgeGxhYignUEMgYW5kIExQQyBjb25jZW50cmF0aW9uIFtubW9sL21sXScpICsgeWxhYignQ29uY2VudHJhdGlvbicpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApCgoKCgpMSV9zZXJ1bS5tZWx0MiA8LSBtZWx0KExJX3NlcnVtLCBpZC52YXJzID0gYygnVGltZScsJ1Byb2JhbmQnKSwgbWVhc3VyZS52YXJzID0gYygnU3VtLk1lbWJyYW5lJywgJ1N1bS5MeXNvJykpCkxJX3NlcnVtLm1lbHQyIDwtIHJlbmFtZShMSV9zZXJ1bS5tZWx0MiwgTEk9dmFyaWFibGUpCkxJX3NlcnVtLm1lbHQyIDwtIHJlbmFtZShMSV9zZXJ1bS5tZWx0MiwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCkxJX3NlcnVtLm1lbHQyJFRpbWUgPC0gZmFjdG9yKExJX3NlcnVtLm1lbHQyJFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIikpCgpnZ3BhaXJlZChMSV9zZXJ1bS5tZWx0MiwgeD0nTEknLCB5PSdDb25jZW50cmF0aW9uJywgY29sb3IgPSAnYmxhY2snLCBmaWxsID0gJ1RpbWUnLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBmYWNldC5ieSA9ICdUaW1lJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFKSArCiAgeGxhYignUEMgYW5kIExQQyBjb25jZW50cmF0aW9uIFtubW9sL21sXScpICsgeWxhYignQ29uY2VudHJhdGlvbicpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApCgoKCgpMSV9zZXJ1bS5tZWx0MyA8LSBtZWx0KExJX3NlcnVtLCBpZC52YXJzID0gYygnVGltZScsJ1Byb2JhbmQnKSwgbWVhc3VyZS52YXJzID0gYygnQ0VSLlNNJywgJ0hleENlci5DRVInKSkKTElfc2VydW0ubWVsdDM8LSByZW5hbWUoTElfc2VydW0ubWVsdDMsIExJPXZhcmlhYmxlKQpMSV9zZXJ1bS5tZWx0MyA8LSByZW5hbWUoTElfc2VydW0ubWVsdDMsIENvbmNlbnRyYXRpb249dmFsdWUpCiAKTElfc2VydW0ubWVsdDMkVGltZSA8LSBmYWN0b3IoTElfc2VydW0ubWVsdDIkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmdncGFpcmVkKExJX3NlcnVtLm1lbHQzLCB4PSdMSScsIHk9J0NvbmNlbnRyYXRpb24nLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywnd2hpdGVzbW9rZScpLCBsaW5lLmNvbG9yID0gJ2dyZXk2MCcsIGxpbmUuc2l6ZSA9IDAuNCwgZ3JvdXAgPSAnUHJvYmFuZCcsIGZhY2V0LmJ5ID0gJ1RpbWUnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdQQyBhbmQgTFBDIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJykgKyB5bGFiKCdDb25jZW50cmF0aW9uJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXM9ImZyZWUiKQoKCgpMSV9zZXJ1bS5tZWx0NCA8LSBtZWx0KExJX3NlcnVtLCBpZC52YXJzID0gYygnVGltZScsJ1Byb2JhbmQnKSwgbWVhc3VyZS52YXJzID0gYygnQ0VSLlNNJywgJ0xQQycpKQpMSV9zZXJ1bS5tZWx0NDwtIHJlbmFtZShMSV9zZXJ1bS5tZWx0NCwgTEk9dmFyaWFibGUpCkxJX3NlcnVtLm1lbHQ0IDwtIHJlbmFtZShMSV9zZXJ1bS5tZWx0NCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKIApMSV9zZXJ1bS5tZWx0NCRUaW1lIDwtIGZhY3RvcihMSV9zZXJ1bS5tZWx0NCRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKZ2dwYWlyZWQoTElfc2VydW0ubWVsdDQsIHg9J0xJJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgZmFjZXQuYnkgPSAnVGltZScsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ1BDIGFuZCBMUEMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nKSArIHlsYWIoJ0NvbmNlbnRyYXRpb24nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcz0iZnJlZSIpCgoKCkxJX3NlcnVtLm1lbHQ1IDwtIG1lbHQoTElfc2VydW0sIGlkLnZhcnMgPSBjKCdUaW1lJywnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdQQy5QRScpKQpMSV9zZXJ1bS5tZWx0NTwtIGRwbHlyOjpyZW5hbWUoTElfc2VydW0ubWVsdDUsIExJPXZhcmlhYmxlKQpMSV9zZXJ1bS5tZWx0NSA8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQ1LCBDb25jZW50cmF0aW9uPXZhbHVlKQoKTElfc2VydW0ubWVsdDUkVGltZSA8LSBmYWN0b3IoTElfc2VydW0ubWVsdDUkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmdncGFpcmVkKExJX3NlcnVtLm1lbHQ1LCB4PSdUaW1lJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgZmFjZXQuYnkgPSAnTEknLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdUaW1lcG9pbnQnKSArIHlsYWIoJ1BDL1BFIHJhdGlvJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgZmFjZXRfZ3JpZCgufiBMSSwgc2NhbGVzPSJmcmVlIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgoKCkxJX3NlcnVtLm1lbHQ2IDwtIG1lbHQoTElfc2VydW0sIGlkLnZhcnMgPSBjKCdUaW1lJywnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdQLlN0b3JhZ2UnLCAnSGV4Q2VyJykpCkxJX3NlcnVtLm1lbHQ2PC0gcmVuYW1lKExJX3NlcnVtLm1lbHQ2LCBMST12YXJpYWJsZSkKTElfc2VydW0ubWVsdDYgPC0gcmVuYW1lKExJX3NlcnVtLm1lbHQ2LCBDb25jZW50cmF0aW9uPXZhbHVlKQpMSV9zZXJ1bS5tZWx0NiRUaW1lIDwtIGZhY3RvcihMSV9zZXJ1bS5tZWx0NiRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKZ2dwYWlyZWQoTElfc2VydW0ubWVsdDYsIHg9J0xJJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgZmFjZXQuYnkgPSAnVGltZScsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ1N0b3JhZ2UgYW5kIE1lbWJyYW5lIGNvbmNlbnRyYXRpb24gWyVdJykgKyB5bGFiKCdDb25jZW50cmF0aW9uJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXM9ImZyZWUiKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCgpMSV9zZXJ1bS5tZWx0NiA8LSBtZWx0KExJX3NlcnVtLCBpZC52YXJzID0gYygnVGltZScsJ1Byb2JhbmQnKSwgbWVhc3VyZS52YXJzID0gYygnTFBDJywgJ1BFJykpCgpMSV9zZXJ1bS5tZWx0NjwtIHJlbmFtZShMSV9zZXJ1bS5tZWx0NiwgTEk9dmFyaWFibGUpCkxJX3NlcnVtLm1lbHQ2IDwtIHJlbmFtZShMSV9zZXJ1bS5tZWx0NiwgQ29uY2VudHJhdGlvbj12YWx1ZSkKTElfc2VydW0ubWVsdDYkVGltZSA8LSBmYWN0b3IoTElfc2VydW0ubWVsdDYkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmdncGFpcmVkKExJX3NlcnVtLm1lbHQ2LCB4PSdMSScsIHk9J0NvbmNlbnRyYXRpb24nLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywnd2hpdGVzbW9rZScpLCBsaW5lLmNvbG9yID0gJ2dyZXk2MCcsIGxpbmUuc2l6ZSA9IDAuNCwgZ3JvdXAgPSAnUHJvYmFuZCcsIGZhY2V0LmJ5ID0gJ1RpbWUnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdTdG9yYWdlIGFuZCBNZW1icmFuZSBjb25jZW50cmF0aW9uIFslXScpICsgeWxhYignQ29uY2VudHJhdGlvbicpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzPSJmcmVlIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpMSV9zZXJ1bS4xIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcy9zZXJ1bSBsaXBpZHMgemFobGVuLjEuMi50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLGhlYWQ9VCkKCgpMSV9zZXJ1bS5tZWx0NiA8LSBtZWx0KExJX3NlcnVtLjEsIGlkLnZhcnMgPSBjKCdQcm9iYW5kJyksIG1lYXN1cmUudmFycyA9IGMoJ1N1bScsICdQRScpKQpMSV9zZXJ1bS5tZWx0NjwtIHJlbmFtZShMSV9zZXJ1bS5tZWx0NiwgTEk9dmFyaWFibGUpCkxJX3NlcnVtLm1lbHQ2IDwtIHJlbmFtZShMSV9zZXJ1bS5tZWx0NiwgQ29uY2VudHJhdGlvbj12YWx1ZSkKTElfc2VydW0ubWVsdDYkVGltZSA8LSBmYWN0b3IoTElfc2VydW0ubWVsdDYkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmdncGFpcmVkKExJX3NlcnVtLm1lbHQ2LCB4PSdMSScsIHk9J0NvbmNlbnRyYXRpb24nLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnTEknLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdTdG9yYWdlIGFuZCBNZW1icmFuZSBjb25jZW50cmF0aW9uIFslXScpICsgeWxhYignQ29uY2VudHJhdGlvbicpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpgYGAKCktvcnJlbGF0aW9uZW4gendpc2NoZW4gZGVuIFNlcnVtbGlwaWRlbiwgdm9uIHdlbGNoZW4gYXVjaCBkaWUgVmVyaMOkbHRuaXNzZSBiZXRyYWNodGV0IHd1cmRlbgoKYGBge3J9CkxJX3NlcnVtLm1lbHQ2IDwtIG1lbHQoTElfc2VydW0sIGlkLnZhcnMgPSBjKCdUaW1lJywnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdMUEMnLCAnUEUnKSkKTElfc2VydW0ubWVsdDY8LSByZW5hbWUoTElfc2VydW0ubWVsdDYsIExJPXZhcmlhYmxlKQpMSV9zZXJ1bS5tZWx0NiA8LSByZW5hbWUoTElfc2VydW0ubWVsdDYsIENvbmNlbnRyYXRpb249dmFsdWUpCgpMSV9zZXJ1bS5tZWx0NiRUaW1lIDwtIGZhY3RvcihMSV9zZXJ1bS5tZWx0NiRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKZ2dwYWlyZWQoTElfc2VydW0ubWVsdDYsIHg9J0xJJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgZmFjZXQuYnkgPSAnVGltZScsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ1N0b3JhZ2UgYW5kIE1lbWJyYW5lIGNvbmNlbnRyYXRpb24gWyVdJykgKyB5bGFiKCdDb25jZW50cmF0aW9uJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXM9ImZyZWUiKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCgoKCkxJX3NlcnVtLm1lbHQ3IDwtIG1lbHQoTElfc2VydW0sIGlkLnZhcnMgPSBjKCdUaW1lJywnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdTTScsICdDRVInKSkKTElfc2VydW0ubWVsdDc8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQ3LCBMST12YXJpYWJsZSkKTElfc2VydW0ubWVsdDcgPC0gZHBseXI6OnJlbmFtZShMSV9zZXJ1bS5tZWx0NywgQ29uY2VudHJhdGlvbj12YWx1ZSkKIApMSV9zZXJ1bS5tZWx0NyRUaW1lIDwtIGZhY3RvcihMSV9zZXJ1bS5tZWx0NyRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKZ2dwYWlyZWQoTElfc2VydW0ubWVsdDcsIHg9J0xJJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgZmFjZXQuYnkgPSAnVGltZScsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ1N0b3JhZ2UgYW5kIE1lbWJyYW5lIGNvbmNlbnRyYXRpb24gWyVdJykgKyB5bGFiKCdDb25jZW50cmF0aW9uJykgKwogIGdlb21fdGV4dChhZXMobGFiZWw9UHJvYmFuZCksaGp1c3Q9MCwgdmp1c3Q9MCkrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXM9ImZyZWUiKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCgoKTElfc2VydW0ubWVsdDggPC0gbWVsdChMSV9zZXJ1bSwgaWQudmFycyA9IGMoJ1RpbWUnLCAnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdDRVIuU00nKSkKTElfc2VydW0ubWVsdDggPC0gZHBseXI6OnJlbmFtZShMSV9zZXJ1bS5tZWx0OCwgTEk9dmFyaWFibGUpCkxJX3NlcnVtLm1lbHQ4IDwtIGRwbHlyOjpyZW5hbWUoTElfc2VydW0ubWVsdDgsIENvbmNlbnRyYXRpb249dmFsdWUpCiAKCmdncGxvdChMSV9zZXJ1bS5tZWx0OCxhZXMoeD1UaW1lLCB5PUNvbmNlbnRyYXRpb24sIGZpbGw9IExJKSkgKwogIHhsYWIgKCdUaW1lIFBvaW50JykgKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0nKSArIAogIGdlb21fYm94cGxvdCgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzID0gYygiQ0VSL1NNIHJhdGlvIiksCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygidG9tYXRvIikpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCgpnZ3BhaXJlZChMSV9zZXJ1bS5tZWx0OCwgeD0nVGltZScsIHk9J0NvbmNlbnRyYXRpb24nLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywnd2hpdGVzbW9rZScpLCBsaW5lLmNvbG9yID0gJ2dyZXk2MCcsIGxpbmUuc2l6ZSA9IDAuNCwgZ3JvdXAgPSAnUHJvYmFuZCcsIGZhY2V0LmJ5ID0gJ0xJJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFKSArCiAgeGxhYignVGltZXBvaW50JykgKyB5bGFiKCdDRVIvU00gcmF0aW8nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICBmYWNldF9ncmlkKC5+IExJLCBzY2FsZXM9ImZyZWUiKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCgoKTElfc2VydW0ubWVsdDkgPC0gbWVsdChMSV9zZXJ1bSwgaWQudmFycyA9IGMoJ1RpbWUnLCdQcm9iYW5kJyksIG1lYXN1cmUudmFycyA9IGMoJ0xQQycsICdQQycpKQpMSV9zZXJ1bS5tZWx0OTwtIGRwbHlyOjpyZW5hbWUoTElfc2VydW0ubWVsdDksIExJPXZhcmlhYmxlKQpMSV9zZXJ1bS5tZWx0OSA8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQ5LCBDb25jZW50cmF0aW9uPXZhbHVlKQoKTElfc2VydW0ubWVsdDkkVGltZSA8LSBmYWN0b3IoTElfc2VydW0ubWVsdDkkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmdncGFpcmVkKExJX3NlcnVtLm1lbHQ5LCB4PSdMSScsIHk9J0NvbmNlbnRyYXRpb24nLCBjb2xvciA9ICdibGFjaycsIGZpbGwgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd3aGl0ZXNtb2tlJywnd2hpdGVzbW9rZScpLCBsaW5lLmNvbG9yID0gJ2dyZXk2MCcsIGxpbmUuc2l6ZSA9IDAuNCwgZ3JvdXAgPSAnUHJvYmFuZCcsIGZhY2V0LmJ5ID0gJ1RpbWUnLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdTdG9yYWdlIGFuZCBNZW1icmFuZSBjb25jZW50cmF0aW9uIFslXScpICsgeWxhYignQ29uY2VudHJhdGlvbicpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzPSJmcmVlIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgoKTElfc2VydW0ubWVsdDExIDwtIG1lbHQoTElfc2VydW0sIGlkLnZhcnMgPSBjKCdUaW1lJywnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdQQycsICdQRScpKQpMSV9zZXJ1bS5tZWx0MTE8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQxMSwgTEk9dmFyaWFibGUpCkxJX3NlcnVtLm1lbHQxMSA8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQxMSwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCkxJX3NlcnVtLm1lbHQxMSRUaW1lIDwtIGZhY3RvcihMSV9zZXJ1bS5tZWx0MTEkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCmdncGFpcmVkKExJX3NlcnVtLm1lbHQxMSwgeD0nTEknLCB5PSdDb25jZW50cmF0aW9uJywgY29sb3IgPSAnYmxhY2snLCBmaWxsID0gJ1RpbWUnLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBmYWNldC5ieSA9ICdUaW1lJywgc2hvcnQucGFuZWwubGFicyA9IEZBTFNFKSArCiAgeGxhYignU3RvcmFnZSBhbmQgTWVtYnJhbmUgY29uY2VudHJhdGlvbiBbJV0nKSArIHlsYWIoJ0NvbmNlbnRyYXRpb24nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcz0iZnJlZSIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL1BDLlBFLktvcnIyLnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQpnZ3NjYXR0ZXIoTElfc2VydW0sIHg9J1BDJywgeT0nUEUnLCBhZGQgPSAncmVnLmxpbmUnLCBjb3IuY29lZi5jb29yZCA9IGMoOTUwLCA4MCksIGNvci5jb2VmLnNpemUgPSA4LGNvbmYuaW50ID0gVFJVRSwKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSxjb2xvciA9ICJncmV5NTkiLGZpbGwgPSAibGlnaHRncmF5IiwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQaG9zcGhhdGlkeWxjaG9saW5rb256ZW50cmF0aW9uZW4gW25tb2wvbWxdJywgeWxhYiA9ICdQaG9zcGhhdGlkeWxldGhhbm9sYW1pbmtvbnplbnRyYXRpb25lbiBbbm1vbC9tbF0nKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIGdlb21fcG9pbnQoY29sb3I9J2dyZXk1MicpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdlb21fcG9pbnQoY29sb3I9J2JsYWNrJywgc2l6ZT0yLjUpCmRldi5vZmYoKQoKY29yLnRlc3Qoc3Vic2V0KGZpbHRlcihMSV9zZXJ1bSkpJFBFLCBzdWJzZXQoZmlsdGVyKExJX3NlcnVtKSkkUEMsIG1ldGhvZCA9ICJzcGVhcm1hbiIsIGV4YWN0ID0gRikKCmNvci50ZXN0KHN1YnNldChmaWx0ZXIoTElfc2VydW0pKSRQRSwgc3Vic2V0KGZpbHRlcihMSV9zZXJ1bSkpJFBDTywgbWV0aG9kID0gInNwZWFybWFuIiwgZXhhY3QgPSBGKQoKY29yLnRlc3Qoc3Vic2V0KGZpbHRlcihMSV9zZXJ1bSkpJFBFLCBzdWJzZXQoZmlsdGVyKExJX3NlcnVtKSkkU00sIG1ldGhvZCA9ICJzcGVhcm1hbiIsIGV4YWN0ID0gRikKCmNvci50ZXN0KHN1YnNldChmaWx0ZXIoTElfc2VydW0pKSRQRSwgc3Vic2V0KGZpbHRlcihMSV9zZXJ1bSkpJFBJLCBtZXRob2QgPSAic3BlYXJtYW4iLCBleGFjdCA9IEYpCgpjb3IudGVzdChzdWJzZXQoZmlsdGVyKExJX3NlcnVtKSkkUEUsIHN1YnNldChmaWx0ZXIoTElfc2VydW0pKSRQRVAsIG1ldGhvZCA9ICJzcGVhcm1hbiIsIGV4YWN0ID0gRikKCmNvci50ZXN0KHN1YnNldChmaWx0ZXIoTElfc2VydW0pKSRQRSwgc3Vic2V0KGZpbHRlcihMSV9zZXJ1bSkpJExQQywgbWV0aG9kID0gInNwZWFybWFuIiwgZXhhY3QgPSBGKQoKY29yLnRlc3Qoc3Vic2V0KGZpbHRlcihMSV9zZXJ1bSkpJFBFLCBzdWJzZXQoZmlsdGVyKExJX3NlcnVtKSkkQ0VSLCBtZXRob2QgPSAic3BlYXJtYW4iLCBleGFjdCA9IEYpCgpwLmFkanVzdChjKDAuNzcwNjQyMyAsMC4wMDAxODg1LDMuOTY0ZS0wNywgNS44MzNlLTE2LCAwLjM5NDcsIDAuMzQyMSwwLjAwNzYxNSApLCBtZXRob2QgPSAnQkgnLCBuPTcpCgpgYGAKClBsb3R0ZW4gZGVyIFNlcnVtbGlwaWQtVmVyaMOkbHRuaXNzZQoKYGBge3J9CgpMSV9zZXJ1bS5tZWx0MTAgPC0gbWVsdChMSV9zZXJ1bSwgaWQudmFycyA9IGMoJ1RpbWUnLCAnUHJvYmFuZCcpLCBtZWFzdXJlLnZhcnMgPSBjKCdMUEMuUEMnKSkKTElfc2VydW0ubWVsdDEwIDwtIGRwbHlyOjpyZW5hbWUoTElfc2VydW0ubWVsdDEwLCBMST12YXJpYWJsZSkKTElfc2VydW0ubWVsdDEwIDwtIGRwbHlyOjpyZW5hbWUoTElfc2VydW0ubWVsdDEwLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKCmdncGxvdChMSV9zZXJ1bS5tZWx0MTAsYWVzKHg9VGltZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBMSSkpICsKICB4bGFiICgnVGltZSBQb2ludCcpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvbWxdJykgKyAKICBnZW9tX2JveHBsb3QoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscyA9IGMoIkxQQy9QQyByYXRpbyIpLAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoInN0ZWVsYmx1ZSIpKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFRSVUUsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKZ2dwYWlyZWQoTElfc2VydW0ubWVsdDEwLCB4PSdUaW1lJywgeT0nQ29uY2VudHJhdGlvbicsIGNvbG9yID0gJ2JsYWNrJywgZmlsbCA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3doaXRlc21va2UnLCd3aGl0ZXNtb2tlJyksIGxpbmUuY29sb3IgPSAnZ3JleTYwJywgbGluZS5zaXplID0gMC40LCBncm91cCA9ICdQcm9iYW5kJywgZmFjZXQuYnkgPSAnTEknLCBzaG9ydC5wYW5lbC5sYWJzID0gRkFMU0UpICsKICB4bGFiKCdUaW1lcG9pbnQnKSArIHlsYWIoJ0xQQy9QQyByYXRpbycpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVByb2JhbmQpLGhqdXN0PTAsIHZqdXN0PTApKwogIGZhY2V0X2dyaWQoLn4gTEksIHNjYWxlcz0iZnJlZSIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKTElfc2VydW0ubWVsdDEyIDwtIG1lbHQoTElfc2VydW0sIGlkLnZhcnMgPSAnVGltZScsIG1lYXN1cmUudmFycyA9IGMoJ1BDLlBFJykpCkxJX3NlcnVtLm1lbHQxMiA8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQxMiwgTEk9dmFyaWFibGUpCkxJX3NlcnVtLm1lbHQxMiA8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQxMiwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCgpnZ3Bsb3QoTElfc2VydW0ubWVsdDEyLGFlcyh4PVRpbWUsIHk9Q29uY2VudHJhdGlvbiwgZmlsbD0gTEkpKSArCiAgeGxhYiAoJ1RpbWUgUG9pbnQnKSArIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXScpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHMgPSBjKCJQQy9QRSByYXRpbyIpLAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoImRhcmtncmVlbiIpKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFRSVUUsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQoKCgpMSV9zZXJ1bS5tZWx0NSA8LSBtZWx0KExJX3NlcnVtLCBpZC52YXJzID0gYygnVGltZScsJ1Byb2JhbmQnKSwgbWVhc3VyZS52YXJzID0gYygnUEMuUEUnKSkKTElfc2VydW0ubWVsdDU8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQ1LCBMST12YXJpYWJsZSkKTElfc2VydW0ubWVsdDUgPC0gZHBseXI6OnJlbmFtZShMSV9zZXJ1bS5tZWx0NSwgQ29uY2VudHJhdGlvbj12YWx1ZSkKIApMSV9zZXJ1bS5tZWx0NSRUaW1lIDwtIGZhY3RvcihMSV9zZXJ1bS5tZWx0NSRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKZ2dwYWlyZWQoTElfc2VydW0ubWVsdDUsIHg9J1RpbWUnLCB5PSdDb25jZW50cmF0aW9uJywgY29sb3IgPSAnYmxhY2snLCBmaWxsID0gJ1RpbWUnLCBwYWxldHRlID0gYygnd2hpdGVzbW9rZScsJ3doaXRlc21va2UnKSwgbGluZS5jb2xvciA9ICdncmV5NjAnLCBsaW5lLnNpemUgPSAwLjQsIGdyb3VwID0gJ1Byb2JhbmQnLCBmYWNldC5ieSA9ICdMSScsIHNob3J0LnBhbmVsLmxhYnMgPSBGQUxTRSkgKwogIHhsYWIoJ1RpbWVwb2ludCcpICsgeWxhYignUEMvUEUgcmF0aW8nKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1Qcm9iYW5kKSxoanVzdD0wLCB2anVzdD0wKSsKICBmYWNldF9ncmlkKC5+IExJLCBzY2FsZXM9ImZyZWUiKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKYGBgCgo2LjIgS29ycmVsYXRpb25zYW5hbHlzZW4gendpc2NoZW4gQ2VyYW1pZCB1bmQgT21lZ2E2LUZBCgpMYWRlbiB1bmQgZmlsdGVybiBkZXIgTWV0YWRhdGVuCgpgYGB7cn0KCkxJX0NFUjYgPC0gcmVhZC50YWJsZSgiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvb21lZ2dhNjpjZXIudHh0Iiwgc2VwID0gJ1x0JywgY29tbWVudD0nJyxoZWFkPVQpCiAKTElfQ0VSNiRUaW1lIDwtIGZhY3RvcihMSV9DRVI2JFRpbWUsIGxldmVscyA9YygiUFJFIiwgIlBPU1QiKSkKCkxJX0NFUjYgPC0gc3Vic2V0KGZpbHRlcihMSV9DRVI2LCAhUHJvYmFuZCA9PSAiMzNNUCIpKQoKYGBgCgpQbG90dGVuIGRlciBLb3JyZWxhdGlvbmVuCgpJbiBBcmJlaXQKCmBgYHtyfQpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvQ2VyYW1pZC5MaW5vbHPDpHVyZS5wZGYiLHdpZHRoPTguNSwgaGVpZ2h0PTEwKQpnZ3NjYXR0ZXIoTElfQ0VSNiwgeD0nQ0VSJywgeT0nTGlub2xzYWV1cmVfbW9sJyxjb2xvciA9ICdUaW1lJyxzaXplID0gMi41LCBwYWxldHRlID0gYygnc2t5Ymx1ZScsICdvcmNoaWQnKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoOCwgMTAwMCksIGNvci5jb2VmLnNpemUgPSA4LCB4bGFiPSAnQ2VyYW1pZCBLb256ZW50cmF0aW9uZW4gW25tb2wvbWxdJywgeWxhYiA9ICdGw6RrYWxlIExpbm9sc8OkdXJla29uemVudHJhdGlvbmVuIFtubW9sL2ddJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmRldi5vZmYoKQoKZ2dzY2F0dGVyKExJX0NFUjYsIHg9J0NFUicsIHk9J0xpbm9sc2FldXJlX21vbCcsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnc2VydW0gY2VyYW1pZGUgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2ZlY2FsIGxpbm9sZWljIGZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCmdnc2NhdHRlcihMSV9DRVI2LCB4PSdDRVInLCB5PSdMaW5vbHNhZXVyZV9pJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdzZXJ1bSBDRVIgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2ZlY2FsIGxpbm9sZWljIGZhdHR5IGFjaWQgY29uY2VudHJhdGlvbiBbbm1vbC9nXScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSkrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmBgYAoKNi4zIEVyc3RlbGxlbiBlaW5lciBLb3JyZWxhdGlvbnNtYXRyaXggenVtIHRlc3RlbiB2b24gS29ycmVsYXRpb25lbiB6d2lzY2hlbiBkZW4gU2VydW1saXBpZGVuCgpGaWx0ZXJuIGbDvHIgUFJFIHVuZCBQT1NUCgpgYGB7cn0KTElfc2VydW1fbWF0cml4X1BSRSA8LSBzdWJzZXQoZmlsdGVyKExJX3NlcnVtLCBUaW1lID09ICJQUkUiKSlbICw3OjI2XQpMSV9zZXJ1bV9tYXRyaXhfUE9TVCA8LSBzdWJzZXQoZmlsdGVyKExJX3NlcnVtLCBUaW1lID09ICJQT1NUIikpWyAsNzoyNl0KCnJlcy5QUkUgPC0gY29yKExJX3NlcnVtX21hdHJpeF9QUkUpCnJlcy5QT1NUIDwtIGNvcihMSV9zZXJ1bV9tYXRyaXhfUE9TVCkKCmBgYAoKU3BlYXJtYW4tUmFuZ2tvcnJlbGF0aW9uIHVuZCBoaW56dWbDvGdlbiB2b24gS29ycmVsYXRpb25rb2VmZml6aWVudCB1bmQgcC12YWx1ZQoKYGBge3J9CnJlczIuUFJFIDwtIHJjb3JyKGFzLm1hdHJpeChMSV9zZXJ1bV9tYXRyaXhfUFJFKSwgdHlwZSA9ICJzcGVhcm1hbiIpCnJlczIuUE9TVCA8LSByY29ycihhcy5tYXRyaXgoTElfc2VydW1fbWF0cml4X1BPU1QpLCB0eXBlID0gInNwZWFybWFuIikKCgpyZXMyLlBSRSRyCnJlczIuUE9TVCRyCgpMSV9zZXJ1bV9QUkVfQ0MgPC0gYXMubWF0cml4KChyZXMyLlBSRSRyKSkKTElfc2VydW1fUE9TVF9DQyA8LSBhcy5tYXRyaXgocmVzMi5QT1NUJHIpCgoKCnJlczIkUAoKTElfc2VydW1fUFJFX1BWIDwtIGFzLm1hdHJpeChyZXMyLlBSRSRQKQpMSV9zZXJ1bV9QT1NUX1BWIDwtIGFzLm1hdHJpeChyZXMyLlBPU1QkUCkKYGBgCgpFcnN0ZWxsZW4gZWluZXIgZmxhdHRlbkNvcnJNYXRyaXggZsO8ciBQUkUgdW5kIFBPU1QKCmBgYHtyfQoKZmxhdHRlbkNvcnJNYXRyaXguUFJFIDwtIGZ1bmN0aW9uKExJX3NlcnVtX1BSRV9DQywgTElfc2VydW1fUFJFX1BWKSB7CiAgdXQgPC0gdXBwZXIudHJpKExJX3NlcnVtX1BSRV9DQykKICBkYXRhLmZyYW1lKAogICAgcm93ID0gcm93bmFtZXMoTElfc2VydW1fUFJFX0NDKVtyb3coTElfc2VydW1fUFJFX0NDKVt1dF1dLAogICAgY29sdW1uID0gcm93bmFtZXMoTElfc2VydW1fUFJFX0NDKVtjb2woTElfc2VydW1fUFJFX0NDKVt1dF1dLAogICAgY29yICA9KExJX3NlcnVtX1BSRV9DQylbdXRdLAogICAgcCA9IExJX3NlcnVtX1BSRV9QVlt1dF0KICApCn0KCmZsYXR0ZW5Db3JyTWF0cml4LlBSRShyZXMyLlBSRSRyLCByZXMyLlBSRSRQKQoKCgpmbGF0dGVuQ29yck1hdHJpeC5QT1NUIDwtIGZ1bmN0aW9uKExJX3NlcnVtX1BPU1RfQ0MsIExJX3NlcnVtX1BPU1RfUFYpIHsKICB1dCA8LSB1cHBlci50cmkoTElfc2VydW1fUE9TVF9DQykKICBkYXRhLmZyYW1lKAogICAgcm93ID0gcm93bmFtZXMoTElfc2VydW1fUE9TVF9DQylbcm93KExJX3NlcnVtX1BPU1RfQ0MpW3V0XV0sCiAgICBjb2x1bW4gPSByb3duYW1lcyhMSV9zZXJ1bV9QT1NUX0NDKVtjb2woTElfc2VydW1fUE9TVF9DQylbdXRdXSwKICAgIGNvciAgPShMSV9zZXJ1bV9QT1NUX0NDKVt1dF0sCiAgICBwID0gTElfc2VydW1fUE9TVF9QVlt1dF0KICApCn0KCmZsYXR0ZW5Db3JyTWF0cml4LlBPU1QocmVzMi5QT1NUJHIsIHJlczIuUE9TVCRQKQoKYGBgCgpEYXRhZnJhbWUgZXJzdGVsbGVuCgpgYGB7cn0KTElfUFJFX2Nvci5wIDwtIGFzLmRhdGEuZnJhbWUoZmxhdHRlbkNvcnJNYXRyaXguUFJFKHJlczIuUFJFJHIsIHJlczIuUFJFJFApKQpMSV9QT1NUX2Nvci5wIDwtIGFzLmRhdGEuZnJhbWUoZmxhdHRlbkNvcnJNYXRyaXguUE9TVChyZXMyLlBPU1QkciwgcmVzMi5QT1NUJFApKQoKY29sbmFtZXMoTElfUFJFX2Nvci5wKSA8LSBjKCJMSSIsICJMSSIsICJjb3JyZWxhdGlvbiBjb2VmZmljaWVudCIsICJwLXZhbHVlIikKCmNvbG5hbWVzKExJX1BPU1RfY29yLnApIDwtIGMoIkxJIiwgIkxJIiwgImNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IiwgInAtdmFsdWUiKQoKYGBgCgpDb3JycGxvdCBlcnN0ZWxsZW4genUgZGVuIFplaXRlbiBQUkUgdW5kIFBPU1QKCmBgYHtyfQpjb3JycGxvdChyZXMuUFJFLCB0eXBlID0gInVwcGVyIiwgb3JkZXIgPSAiaGNsdXN0IiwgCiAgICAgICAgIHRsLmNvbCA9ICJibGFjayIsIHRsLnNydCA9IDQ1KQoKY29ycnBsb3QocmVzLlBPU1QsIHR5cGUgPSAidXBwZXIiLCBvcmRlciA9ICJoY2x1c3QiLCAKICAgICAgICAgdGwuY29sID0gImJsYWNrIiwgdGwuc3J0ID0gNDUpCgoKY29ycnBsb3QocmVzMi5QUkUkciwgdHlwZT0idXBwZXIiLCBvcmRlcj0iaGNsdXN0IiwgCiAgICAgICAgIHAubWF0ID0gcmVzMi5QUkUkUCwgc2lnLmxldmVsID0gMC4wNSwgaW5zaWcgPSAiYmxhbmsiKQoKY29ycnBsb3QocmVzMi5QUkUkciwgdHlwZT0idXBwZXIiLCBvcmRlcj0iaGNsdXN0IiwgCiAgICAgICAgIHAubWF0ID0gcmVzMi5QUkUkUCwgc2lnLmxldmVsID0gMC4wNSwgaW5zaWcgPSAiYmxhbmsiKQpgYGAKClNjYXR0ZXJwbG90cyBlcnN0ZWxsZW4genUgZGVuIFplaXRlbiBQUkUgdW5kIFBPU1QKCmBgYHtyfQpjaGFydC5Db3JyZWxhdGlvbihMSV9zZXJ1bV9tYXRyaXhfUFJFLCBoaXN0b2dyYW09VFJVRSwgcGNoPTE5KQpjaGFydC5Db3JyZWxhdGlvbihTQ0ZBX3N0b29sX21hdHJpeF9QT1NULCBoaXN0b2dyYW0gPSBULCBwY2ggPSAxOSkKYGBgCgo2LjQgVW50ZXJzY2hpZWRlIGRlciBTZXJ1bWxpcGlka29uemVudHJhdGlvbmVuIHp3aXNjaGVuIFN0ZXJvbGtvbnZlcnRpZXJ1bmdzdHlwZW4KCkxhZGVuIHVuZCBmaWx0ZXJuIGRlciBEYXRlbiBMaXBpZG1ldGFkYXRlbiBzLm8uCkluIGhpZ2ggdW5kIGxvdyBjb252ZXJ0ZXIgdW50ZXJ0ZWlsZW4KCmBgYHtyfQoKbG93Y29udiA8LSBmaWx0ZXIoTElfc2VydW0sIFByb2JhbmQgPT0gIjA1QVAiIHwgUHJvYmFuZCA9PSAiMzNNUCIKICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzhBUiIgfCBQcm9iYW5kID09ICI0MFdBIiB8IFByb2JhbmQgPT0gIjQxTUwiCiAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjQ3T1QiIHwgUHJvYmFuZCA9PSAiNDlSSiIgfCBQcm9iYW5kID09ICI1MERNIikKCmxvd2NvbnZbJ1BoZW5vdHlwZSddID0gJ2xvdyBjb252ZXJ0ZXInCgpoaWdoY29udiA8LSBmaWx0ZXIoTElfc2VydW0sIFByb2JhbmQgPT0gIjA2V1QiIHwgUHJvYmFuZCA9PSAiMDdSVyIKICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIxM0JTIiB8IFByb2JhbmQgPT0gIjE3U0siIHwgUHJvYmFuZCA9PSAiMjJXUyIKICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIyNUZFIiB8IFByb2JhbmQgPT0gIjI2RkIiIHwgUHJvYmFuZCA9PSAiMjlNSyIKICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzMEhCIiB8IFByb2JhbmQgPT0gIjMxS0UiIHwgUHJvYmFuZCA9PSAiMzZFUiIKICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI0NUdMIiB8IFByb2JhbmQgPT0gIjUzQkQiIHwgUHJvYmFuZCA9PSAiNTRTTCIKICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI1N01UIiB8IFByb2JhbmQgPT0gIjY5SEwiIHwgUHJvYmFuZCA9PSAiNzRTQSIpCgpoaWdoY29udlsnUGhlbm90eXBlJ10gPSAnaGlnaCBjb252ZXJ0ZXInCgpoaWdoY29udiRDb252ZXJ0ZXIuVHlwZSA8LSBOVUxMCmxvd2NvbnYkQ29udmVydGVyLlR5cGUgPC0gTlVMTAoKbm9jb252IDwtIGZpbHRlcihMSV9zZXJ1bSwgUHJvYmFuZCA9PSAiMjhITSIgfCBQcm9iYW5kID09ICIzMkZHIgogICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzRXRiIgfCBQcm9iYW5kID09ICIzNUFEIiB8IFByb2JhbmQgPT0gIjM3U0QiCiAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIzOURBIiB8IFByb2JhbmQgPT0gIjY2REciIHwgUHJvYmFuZCA9PSAiNzBQTCIpCgpub2NvbnZbJ1BoZW5vdHlwZSddID0gJ25vdCBjbGFzc2lmaWVkJwoKbm9jb252JENvbnZlcnRlci5UeXBlIDwtIE5VTEwKCmNvbnZUIDwtIGRhdGEuZnJhbWUoKQpjb252VCA8LSBiaW5kX3Jvd3MobG93Y29udiwgaGlnaGNvbnYsIG5vY29udikKCmNvbnZUX3BhaXJlZCA8LSBmaWx0ZXIoY29udlQsIFByb2JhbmQgPT0gIjA1QVAiIHwgUHJvYmFuZCA9PSAiMDZXVCIKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjA3UlciIHwgUHJvYmFuZCA9PSAiMTNCUyIgfCBQcm9iYW5kID09ICIxN1NLIgogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMjJXUyIgfCBQcm9iYW5kID09ICIyNUZFIiB8IFByb2JhbmQgPT0gIjI2RkIiCiAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICIyOEhNIiB8IFByb2JhbmQgPT0gIjI5TUsiIHwgUHJvYmFuZCA9PSAiMzBIQiIKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjMxS0UiIHwgUHJvYmFuZCA9PSAiMzJGRyIgfCBQcm9iYW5kID09ICIzNkVSIgogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiMzdTRCIgfCBQcm9iYW5kID09ICIzOEFSIiB8IFByb2JhbmQgPT0gIjQwV0EiCiAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgfCBQcm9iYW5kID09ICI0MU1MIiB8IFByb2JhbmQgPT0gIjQ1R0wiIHwgUHJvYmFuZCA9PSAiNDdPVCIKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICB8IFByb2JhbmQgPT0gIjUwRE0iIHwgUHJvYmFuZCA9PSAiNTNCRCIgfCBQcm9iYW5kID09ICI1NFNMIgogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgIHwgUHJvYmFuZCA9PSAiNTdNVCIgfCBQcm9iYW5kID09ICI2OUhMIiB8IFByb2JhbmQgPT0gIjc0U0EiKQoKYGBgCgpQbG90dGVuIGRlciBVbnRlcnNjaGllZGUgZGVyIFNlcnVtbGlwaWRrb256ZW50cmF0aW9uZW4gendpc2NoZW4gZGVuIFN0ZXJvbGtvbnZlcnRpZXJ1bmdzdHlwZW4KCmBgYHtyfQpMSV9zZXJ1bS5tZWx0IDwtIG1lbHQoY29udlRfcGFpcmVkLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywgJ1RpbWUnKSwgbWVhc3VyZS52YXJzID0gYygnUEMnLCAnUENPJywgJ1NNJywgJ1BFJywgJ1BJJywnUEVQJywgJ0xQQycsICdDRVInLCAnSGV4Q2VyJykpCkxJX3NlcnVtLm1lbHQgPC0gc3Vic2V0KGZpbHRlcihMSV9zZXJ1bS5tZWx0LCAhUGhlbm90eXBlID09ICJub3QgY2xhc3NpZmllZCIpKQpMSV9zZXJ1bS5tZWx0IDwtIHJlbmFtZShMSV9zZXJ1bS5tZWx0LCB2YXJpYWJsZT1MSSkKTElfc2VydW0ubWVsdCA8LSByZW5hbWUoTElfc2VydW0ubWVsdCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKCiBnZ3Bsb3QoTElfc2VydW0ubWVsdCxhZXMoeD1QaGVub3R5cGUsIHk9dmFsdWUsIGZpbGw9IHZhcmlhYmxlKSkgKwogIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvbWxdJykgKyAKICBnZW9tX2JveHBsb3QoKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgZmFjZXRfZ3JpZCguflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCgogIApMSV9zZXJ1bS5tZWx0MSA8LSBtZWx0KGNvbnZUX3BhaXJlZCwgaWQudmFycyA9IGMoJ1BoZW5vdHlwZScsICdUaW1lJyksIG1lYXN1cmUudmFycyA9IGMoJ1N1bScsICdTdW0uTWVtYnJhbmUnLCdTdW0uU3RvcmFnZScsICdTdW0uTHlzbycpKQpMSV9zZXJ1bS5tZWx0MSA8LSBzdWJzZXQoZmlsdGVyKExJX3NlcnVtLm1lbHQxLCAhUGhlbm90eXBlID09ICJub3QgY2xhc3NpZmllZCIpKQpMSV9zZXJ1bS5tZWx0MSA8LSByZW5hbWUoTElfc2VydW0ubWVsdDEsIHZhcmlhYmxlPUxJKQpMSV9zZXJ1bS5tZWx0MSA8LSByZW5hbWUoTElfc2VydW0ubWVsdDEsIENvbmNlbnRyYXRpb249dmFsdWUpCgogIGdncGxvdChMSV9zZXJ1bS5tZWx0MSxhZXMoeD1QaGVub3R5cGUsIHk9dmFsdWUsIGZpbGw9IHZhcmlhYmxlKSkgKwogIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpICsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvbWxdJykgKyAKICBnZW9tX2JveHBsb3QoKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgZmFjZXRfZ3JpZCguflRpbWUpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikrCiAgICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpCmBgYAoKUGxvdHRlbiBkZXIgVW50ZXJzY2hpZWRlIGRlciBTZXJ1bWxpcGlkdmVyaMOkbHRuaXNzZSB6d2lzY2hlbiBkZW4gU3Rlcm9sa29udmVydGllcnVuZ3N0eXBlbgoKYGBge3J9CgpMSS5yMSA8LSBtZWx0KGNvbnZUX3BhaXJlZCwgaWQudmFycyA9IGMoJ1BoZW5vdHlwZScsJ1RpbWUnKSwgbWVhc3VyZS52YXJzID0gYygnTFBDLlBDJykpCiAgCiAgZ2dwbG90KGZpbHRlcihMSS5yMSwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9UGhlbm90eXBlLCB5PXZhbHVlLCBmaWxsPSB2YXJpYWJsZSkpICsKICAgIGZhY2V0X2dyaWQoLn4gVGltZSkgKwogICAgeGxhYiAoJ0NvbnZlcnRlciB0eXBlJykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXSAnKSArIAogICAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoIkxQQy9QQyIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJoaWdoIGNvbnZlcnRlciIsICJsb3cgY29udmVydGVyIikpKSsKICAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAogIGdncGxvdChmaWx0ZXIoTEkuU3VtLm0sICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVRpbWUsIHk9dmFsdWUsIGZpbGw9IHZhcmlhYmxlKSkgKwogICAgZmFjZXRfZ3JpZCgufiBQaGVub3R5cGUpICsKICAgIHhsYWIgKCdUaW1lIFBvaW50JykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXScpICsgCiAgICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9Yygic3VtIG1lbWJyYW5lIiksIHZhbHVlcyA9IGMoInN0ZWVsYmx1ZTIiKSkrCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKICAKICAKICAKICAKICBMSS5yMiA8LSBtZWx0KGNvbnZUX3BhaXJlZCwgaWQudmFycyA9IGMoJ1BoZW5vdHlwZScsJ1RpbWUnKSwgbWVhc3VyZS52YXJzID0gYygnQ0VSLlNNJykpCiAgCiAgZ2dwbG90KGZpbHRlcihMSS5yMiwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9UGhlbm90eXBlLCB5PXZhbHVlLCBmaWxsPSB2YXJpYWJsZSkpICsKICAgIGZhY2V0X2dyaWQoLn4gVGltZSkgKwogICAgeGxhYiAoJ0NvbnZlcnRlciB0eXBlJykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXSAnKSArIAogICAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoIkNFUi9TTSIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJoaWdoIGNvbnZlcnRlciIsICJsb3cgY29udmVydGVyIikpKSsKICAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAogIGdncGxvdChmaWx0ZXIoTEkuU3VtLm0sICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVRpbWUsIHk9dmFsdWUsIGZpbGw9IHZhcmlhYmxlKSkgKwogICAgZmFjZXRfZ3JpZCgufiBQaGVub3R5cGUpICsKICAgIHhsYWIgKCdUaW1lIFBvaW50JykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXScpICsgCiAgICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9Yygic3VtIG1lbWJyYW5lIiksIHZhbHVlcyA9IGMoInN0ZWVsYmx1ZTIiKSkrCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCiAgCiAgCiAgCiAgCiAgTElfc2VydW0ubWVsdDIgPC0gbWVsdChjb252VF9wYWlyZWQsIGlkLnZhcnMgPSBjKCdQaGVub3R5cGUnLCAnVGltZScpLCBtZWFzdXJlLnZhcnMgPSBjKCAnUEMuUEUnKSkKICBMSV9zZXJ1bS5tZWx0MiA8LSBzdWJzZXQoZmlsdGVyKExJX3NlcnVtLm1lbHQyLCAhUGhlbm90eXBlID09ICJub3QgY2xhc3NpZmllZCIpKQogIExJX3NlcnVtLm1lbHQyIDwtIGRwbHlyOjpyZW5hbWUoTElfc2VydW0ubWVsdDIsIHZhcmlhYmxlPSBMSSkKICBMSV9zZXJ1bS5tZWx0MiA8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQyLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKICAKICBjb21wYXJpc29uX2NvbnYgPC0gbGlzdChjKCJsb3cgY29udmVydGVyIiwgImhpZ2ggY29udmVydGVyIikpCiAgY29tcGFyaXNvbl90aW1lIDwtIGxpc3QoYygiUFJFIiwgIlBPU1QiKSkKICAKICBnZ3Bsb3QoTElfc2VydW0ubWVsdDIsYWVzKHg9UGhlbm90eXBlLCB5PXZhbHVlLCBmaWxsPSB2YXJpYWJsZSkpICsKICAgIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpICsgeWxhYiAoJ1BDL1BFIHJhdGlvJykgKyAKICAgIGdlb21fYm94cGxvdCgpKwogICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCBoanVzdD0xKSkrCiAgICBmYWNldF9ncmlkKC5+VGltZSkrCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiaGlnaCBjb252ZXJ0ZXIiLCAibG93IGNvbnZlcnRlciIpKSkrCiAgICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKQogIAogIGdncGxvdChMSV9zZXJ1bS5tZWx0MixhZXMoeD1UaW1lLCB5PXZhbHVlLCBmaWxsPSB2YXJpYWJsZSkpICsKICAgIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpICsgeWxhYiAoJ1BDL1BFIHJhdGlvJykgKyAKICAgIGdlb21fYm94cGxvdCgpKwogICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTAsIGhqdXN0PTEpKSsKICAgIGZhY2V0X2dyaWQoLn5QaGVub3R5cGUpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkKYGBgCgpXaWxjb3hvbi1UZXN0LCBtZWFuIHVuZCBTRCwgUGxvdHRlbiBkZXIgVW50ZXJzY2hpZWRlIGRlcyBQQy9QRS1WZXJow6RsdG5pc3NlcyB6d2lzY2hlbiBkZW4gU3Rlcm9sa29udmVydGllcnVuZ3N0eXBlbgpJbiBBcmJlaXQKCmBgYHtyfQoKICBtZWFuKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkLCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJoaWdoIGNvbnZlcnRlciIpKSRQQy5QRSkgCiAgCiAgc2Qoc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWQsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gImhpZ2ggY29udmVydGVyIikpJFBDLlBFKSAKICAKICBtZWFuKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkLCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAiaGlnaCBjb252ZXJ0ZXIiKSkkUEMuUEUpIAogIAogIHNkKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkLCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAiaGlnaCBjb252ZXJ0ZXIiKSkkUEMuUEUpIAogIAogIAogIG1lYW4oc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWQsIFRpbWUgPT0gIlBSRSIgJiBQaGVub3R5cGUgPT0gImxvdyBjb252ZXJ0ZXIiKSkkUEMuUEUpIAogIAogIHNkKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkLCBUaW1lID09ICJQUkUiICYgUGhlbm90eXBlID09ICJsb3cgY29udmVydGVyIikpJFBDLlBFKSAKICAKICBtZWFuKHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkLCBUaW1lID09ICJQT1NUIiAmIFBoZW5vdHlwZSA9PSAibG93IGNvbnZlcnRlciIpKSRQQy5QRSkgCiAgCiAgc2Qoc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWQsIFRpbWUgPT0gIlBPU1QiICYgUGhlbm90eXBlID09ICJsb3cgY29udmVydGVyIikpJFBDLlBFKSAKICAKICAKICBwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGNvbnZUX3BhaXJlZCwgVGltZSA9PSAiUFJFIikpJFBDLlBFLCBzdWJzZXQoZmlsdGVyKGNvbnZUX3BhaXJlZCwgVGltZSA9PSAiUFJFIikpJFBoZW5vdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gJ0JIJywgcGFpcmVkID0gRikKICAKICBwYWlyd2lzZS53aWxjb3gudGVzdChzdWJzZXQoZmlsdGVyKGNvbnZUX3BhaXJlZCwgVGltZSA9PSAiUE9TVCIpKSRQQy5QRSwgc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWQsIFRpbWUgPT0gIlBPU1QiKSkkUGhlbm90eXBlLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKSAgICAgICAgICAgICAgCiAgCiAgcGFpcndpc2Uud2lsY294LnRlc3Qoc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWQsIFBoZW5vdHlwZSA9PSAibG93IGNvbnZlcnRlciIpKSRQQy5QRSwgc3Vic2V0KGZpbHRlcihjb252VF9wYWlyZWQsIFBoZW5vdHlwZSA9PSAibG93IGNvbnZlcnRlciIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQogIAogIHBhaXJ3aXNlLndpbGNveC50ZXN0KHN1YnNldChmaWx0ZXIoY29udlRfcGFpcmVkLCBQaGVub3R5cGUgPT0gImhpZ2ggY29udmVydGVyIikpJFBDLlBFLCBzdWJzZXQoZmlsdGVyKGNvbnZUX3BhaXJlZCwgUGhlbm90eXBlID09ICJoaWdoIGNvbnZlcnRlciIpKSRUaW1lLCBwLmFkanVzdC5tZXRob2QgPSAnQkgnLCBwYWlyZWQgPSBGKQogCiAgCiAgCiAgCiAgCiAgTEkucjIgPC0gbWVsdChjb252VF9wYWlyZWQsIGlkLnZhcnMgPSBjKCdQaGVub3R5cGUnLCdUaW1lJyksIG1lYXN1cmUudmFycyA9IGMoJ1BDLlBFJykpCiAgTEkucjIgPC0gcmVuYW1lKCAgTEkucjIsIExJPXZhcmlhYmxlKQogIExJLnIyIDwtIHJlbmFtZSggIExJLnIyLCBDb25jZW50cmF0aW9uPXZhbHVlKQoKICBwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvY29udmVydGVyLlBDLlBFLnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQogIGdncGxvdChmaWx0ZXIoTEkucjIsICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT1Db25jZW50cmF0aW9uLCBmaWxsPSBQaGVub3R5cGUpKSArCiAgICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICAgIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpKyB5bGFiICgnUGhvc3BoYXRpZHlsY2hvbGluL1Bob3NwaGF0aWR5bGV0aGFub2xhbWluIFZlcmjDpGx0bmlzJykgKyAKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJoaWdoIGNvbnZlcnRlciIsICJsb3cgY29udmVydGVyIiksIHZhbHVlcyA9IGMoInNlYXNoZWxsNCIsICJzZWFzaGVsbDIiKSkrCiAgICBnZW9tX2JveHBsb3Qod2lkdGggPSAuNywgbHdkPTAuNikgKyB0aGVtZV9jbGFzc2ljKCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJsb3cgY29udmVydGVyIikpKSsKICAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGNvbG91ciA9ICJibGFjayIpKSsKICAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCwgY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0wLCBoanVzdD0xKSkrCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQogIGRldi5vZmYoKQogIAogIGdncGxvdChmaWx0ZXIoTEkucjIsICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT12YWx1ZSwgZmlsbD0gdmFyaWFibGUpKSArCiAgICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICAgIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0gJykgKyAKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJQQy9QRSIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJoaWdoIGNvbnZlcnRlciIsICJsb3cgY29udmVydGVyIikpKSsKICAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAogIGdncGxvdChmaWx0ZXIoTEkuU3VtLm0sICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVRpbWUsIHk9dmFsdWUsIGZpbGw9IHZhcmlhYmxlKSkgKwogICAgZmFjZXRfZ3JpZCgufiBQaGVub3R5cGUpICsKICAgIHhsYWIgKCdUaW1lIFBvaW50JykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXScpICsgCiAgICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9Yygic3VtIG1lbWJyYW5lIiksIHZhbHVlcyA9IGMoInN0ZWVsYmx1ZTIiKSkrCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKCmBgYAoKUGxvdHRlbiBkZXIgVW50ZXJzY2hpZWRlIGVpbnplbG5lciBTZXJ1bWxpcGlka29uemVudHJhdGlvbmVuIHp3aXNjaGVuIGRlbiBTdGVyb2xrb252ZXJ0aWVydW5nc3R5cGVuCgpgYGB7cn0KTEkuUENPIDwtIG1lbHQoY29udlRfcGFpcmVkLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywnVGltZScpLCBtZWFzdXJlLnZhcnMgPSBjKCdQQ08nKSkKICBMSS5QQ08gPC0gcmVuYW1lKExJLlBDTywgRkE9dmFyaWFibGUpCiAgTEkuUENPIDwtIHJlbmFtZShMSS5QQ08sIENvbmNlbnRyYXRpb249dmFsdWUpCiAgCiAgZ2dwbG90KGZpbHRlcihMSS5QQ08sICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT12YWx1ZSwgZmlsbD0gdmFyaWFibGUpKSArCiAgICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICAgIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0gJykgKyAKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJQQ08iKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIpKSsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiaGlnaCBjb252ZXJ0ZXIiLCAibG93IGNvbnZlcnRlciIpKSkrCiAgICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKICAKICBnZ3Bsb3QoZmlsdGVyKExJLlBDTywgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9VGltZSwgeT12YWx1ZSwgZmlsbD0gdmFyaWFibGUpKSArCiAgICBmYWNldF9ncmlkKC5+IFBoZW5vdHlwZSkgKwogICAgeGxhYiAoJ1RpbWUgUG9pbnQnKSsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvbWxdJykgKyAKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJQQ08iKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIpKSsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBULCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAogIAogIAogIAogIExJLlNNIDwtIG1lbHQoY29udlRfcGFpcmVkLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywnVGltZScpLCBtZWFzdXJlLnZhcnMgPSBjKCdTTScpKQogIExJLlNNIDwtIHJlbmFtZShMSS5TTSwgRkE9dmFyaWFibGUpCiAgTEkuU00gPC0gcmVuYW1lKExJLlNNLCBDb25jZW50cmF0aW9uPXZhbHVlKQogIAogIGdncGxvdChmaWx0ZXIoTEkuU00sICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT12YWx1ZSwgZmlsbD0gdmFyaWFibGUpKSArCiAgICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICAgIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0gJykgKyAKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJTTSIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJoaWdoIGNvbnZlcnRlciIsICJsb3cgY29udmVydGVyIikpKSsKICAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAogIGdncGxvdChmaWx0ZXIoTEkuU00sICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVRpbWUsIHk9dmFsdWUsIGZpbGw9IHZhcmlhYmxlKSkgKwogICAgZmFjZXRfZ3JpZCgufiBQaGVub3R5cGUpICsKICAgIHhsYWIgKCdUaW1lIFBvaW50JykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXScpICsgCiAgICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiU00iKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIpKSsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBULCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAogIAogIAoKICBMSS5QRSA8LSBtZWx0KGNvbnZUX3BhaXJlZCwgaWQudmFycyA9IGMoJ1BoZW5vdHlwZScsJ1RpbWUnKSwgbWVhc3VyZS52YXJzID0gYygnUEUnKSkKICBMSS5QRSA8LSByZW5hbWUoTEkuUEUsIEZBPXZhcmlhYmxlKQogIExJLlBFIDwtIHJlbmFtZShMSS5QRSwgQ29uY2VudHJhdGlvbj12YWx1ZSkKICAKICBnZ3Bsb3QoZmlsdGVyKExJLlBFLCAhUGhlbm90eXBlPT0ibm90IGNsYXNzaWZpZWQiKSxhZXMoeD1QaGVub3R5cGUsIHk9dmFsdWUsIGZpbGw9IHZhcmlhYmxlKSkgKwogICAgZmFjZXRfZ3JpZCgufiBUaW1lKSArCiAgICB4bGFiICgnQ29udmVydGVyIHR5cGUnKSsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvbWxdICcpICsgCiAgICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiUEUiKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIpKSsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiaGlnaCBjb252ZXJ0ZXIiLCAibG93IGNvbnZlcnRlciIpKSkrCiAgICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKICAKICBnZ3Bsb3QoZmlsdGVyKExJLlNNLCAhUGhlbm90eXBlPT0ibm90IGNsYXNzaWZpZWQiKSxhZXMoeD1UaW1lLCB5PXZhbHVlLCBmaWxsPSB2YXJpYWJsZSkpICsKICAgIGZhY2V0X2dyaWQoLn4gUGhlbm90eXBlKSArCiAgICB4bGFiICgnVGltZSBQb2ludCcpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0nKSArIAogICAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoIlNNIiksIHZhbHVlcyA9IGMoInN0ZWVsYmx1ZTIiKSkrCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKICAKICAKIAogIAogIExJLlBJIDwtIG1lbHQoY29udlRfcGFpcmVkLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywnVGltZScpLCBtZWFzdXJlLnZhcnMgPSBjKCdQSScpKQogIExJLlBJIDwtIHJlbmFtZShMSS5QSSwgRkE9dmFyaWFibGUpCiAgTEkuUEkgPC0gcmVuYW1lKExJLlBJLCBDb25jZW50cmF0aW9uPXZhbHVlKQogIAogIGdncGxvdChmaWx0ZXIoTEkuUEksICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT12YWx1ZSwgZmlsbD0gdmFyaWFibGUpKSArCiAgICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICAgIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0gJykgKyAKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJQSSIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJoaWdoIGNvbnZlcnRlciIsICJsb3cgY29udmVydGVyIikpKSsKICAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAogIGdncGxvdChmaWx0ZXIoTEkuUEksICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVRpbWUsIHk9dmFsdWUsIGZpbGw9IHZhcmlhYmxlKSkgKwogICAgZmFjZXRfZ3JpZCgufiBQaGVub3R5cGUpICsKICAgIHhsYWIgKCdUaW1lIFBvaW50JykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXScpICsgCiAgICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiUEkiKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIpKSsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBULCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAoKICAKICAKICBMSS5QRVAgPC0gbWVsdChjb252VF9wYWlyZWQsIGlkLnZhcnMgPSBjKCdQaGVub3R5cGUnLCdUaW1lJyksIG1lYXN1cmUudmFycyA9IGMoJ1BFUCcpKQogIExJLlBFUCA8LSByZW5hbWUoTEkuUEVQLCBGQT12YXJpYWJsZSkKICBMSS5QRVAgPC0gcmVuYW1lKExJLlBFUCwgQ29uY2VudHJhdGlvbj12YWx1ZSkKICAKICBnZ3Bsb3QoZmlsdGVyKExJLlBFUCwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9UGhlbm90eXBlLCB5PXZhbHVlLCBmaWxsPSB2YXJpYWJsZSkpICsKICAgIGZhY2V0X2dyaWQoLn4gVGltZSkgKwogICAgeGxhYiAoJ0NvbnZlcnRlciB0eXBlJykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXSAnKSArIAogICAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoIlBFUCIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJoaWdoIGNvbnZlcnRlciIsICJsb3cgY29udmVydGVyIikpKSsKICAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAogIGdncGxvdChmaWx0ZXIoTEkuUEVQLCAhUGhlbm90eXBlPT0ibm90IGNsYXNzaWZpZWQiKSxhZXMoeD1UaW1lLCB5PXZhbHVlLCBmaWxsPSB2YXJpYWJsZSkpICsKICAgIGZhY2V0X2dyaWQoLn4gUGhlbm90eXBlKSArCiAgICB4bGFiICgnVGltZSBQb2ludCcpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0nKSArIAogICAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoIlBFUCIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFQsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkrCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCiAgCiAgCgogIAogIExJLkxQQyA8LSBtZWx0KGNvbnZUX3BhaXJlZCwgaWQudmFycyA9IGMoJ1BoZW5vdHlwZScsJ1RpbWUnKSwgbWVhc3VyZS52YXJzID0gYygnTFBDJykpCiAgTEkuTFBDIDwtIHJlbmFtZShMSS5MUEMsIEZBPXZhcmlhYmxlKQogIExJLkxQQyA8LSByZW5hbWUoTEkuTFBDLCBDb25jZW50cmF0aW9uPXZhbHVlKQogIAogIAogIGdncGxvdChmaWx0ZXIoTEkuTFBDLCAhUGhlbm90eXBlPT0ibm90IGNsYXNzaWZpZWQiKSxhZXMoeD1QaGVub3R5cGUsIHk9dmFsdWUsIGZpbGw9IHZhcmlhYmxlKSkgKwogICAgZmFjZXRfZ3JpZCgufiBUaW1lKSArCiAgICB4bGFiICgnQ29udmVydGVyIHR5cGUnKSsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvbWxdICcpICsgCiAgICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiTFBDIiksIHZhbHVlcyA9IGMoInN0ZWVsYmx1ZTIiKSkrCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gRiwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoImhpZ2ggY29udmVydGVyIiwgImxvdyBjb252ZXJ0ZXIiKSkpKwogICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCiAgCiAgZ2dwbG90KGZpbHRlcihMSS5MUEMsICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVRpbWUsIHk9dmFsdWUsIGZpbGw9IHZhcmlhYmxlKSkgKwogICAgZmFjZXRfZ3JpZCgufiBQaGVub3R5cGUpICsKICAgIHhsYWIgKCdUaW1lIFBvaW50JykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXScpICsgCiAgICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiTFBDIiksIHZhbHVlcyA9IGMoInN0ZWVsYmx1ZTIiKSkrCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKICAKCiAgCiAgCiAgTEkuQ0VSIDwtIG1lbHQoY29udlRfcGFpcmVkLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywnVGltZScpLCBtZWFzdXJlLnZhcnMgPSBjKCdDRVInKSkKICAKICBnZ3Bsb3QoZmlsdGVyKExJLkNFUiwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9UGhlbm90eXBlLCB5PXZhbHVlLCBmaWxsPSB2YXJpYWJsZSkpICsKICAgIGZhY2V0X2dyaWQoLn4gVGltZSkgKwogICAgeGxhYiAoJ0NvbnZlcnRlciB0eXBlJykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXSAnKSArIAogICAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoIkNFUiIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJoaWdoIGNvbnZlcnRlciIsICJsb3cgY29udmVydGVyIikpKSsKICAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAogIGdncGxvdChmaWx0ZXIoTEkuTFBDLCAhUGhlbm90eXBlPT0ibm90IGNsYXNzaWZpZWQiKSxhZXMoeD1UaW1lLCB5PXZhbHVlLCBmaWxsPSB2YXJpYWJsZSkpICsKICAgIGZhY2V0X2dyaWQoLn4gUGhlbm90eXBlKSArCiAgICB4bGFiICgnVGltZSBQb2ludCcpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0nKSArIAogICAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoIkxQQyIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFQsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkrCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCiAgCiAgCgogIAogIExJLkhleENlciA8LSBtZWx0KGNvbnZUX3BhaXJlZCwgaWQudmFycyA9IGMoJ1BoZW5vdHlwZScsJ1RpbWUnKSwgbWVhc3VyZS52YXJzID0gYygnSGV4Q2VyJykpCiAgCiAgZ2dwbG90KGZpbHRlcihMSS5IZXhDZXIsICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT12YWx1ZSwgZmlsbD0gdmFyaWFibGUpKSArCiAgICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICAgIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0gJykgKyAKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJIRVhDRVIiKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIpKSsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiaGlnaCBjb252ZXJ0ZXIiLCAibG93IGNvbnZlcnRlciIpKSkrCiAgICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKICAKICBnZ3Bsb3QoZmlsdGVyKExJLkhleENlciwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9VGltZSwgeT12YWx1ZSwgZmlsbD0gdmFyaWFibGUpKSArCiAgICBmYWNldF9ncmlkKC5+IFBoZW5vdHlwZSkgKwogICAgeGxhYiAoJ1RpbWUgUG9pbnQnKSsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvbWxdJykgKyAKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJIZXhDZXIiKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIpKSsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBULCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAogIAoKICAKIAogIExJLlN1bSA8LSBtZWx0KGNvbnZUX3BhaXJlZCwgaWQudmFycyA9IGMoJ1BoZW5vdHlwZScsJ1RpbWUnKSwgbWVhc3VyZS52YXJzID0gYygnU3VtJykpCiAgCiAgZ2dwbG90KGZpbHRlcihMSS5TdW0sICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT12YWx1ZSwgZmlsbD0gdmFyaWFibGUpKSArCiAgICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICAgIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0gJykgKyAKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJTVU0iKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIpKSsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiaGlnaCBjb252ZXJ0ZXIiLCAibG93IGNvbnZlcnRlciIpKSkrCiAgICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKICAKICBnZ3Bsb3QoZmlsdGVyKExJLkhleENlciwgIVBoZW5vdHlwZT09Im5vdCBjbGFzc2lmaWVkIiksYWVzKHg9VGltZSwgeT12YWx1ZSwgZmlsbD0gdmFyaWFibGUpKSArCiAgICBmYWNldF9ncmlkKC5+IFBoZW5vdHlwZSkgKwogICAgeGxhYiAoJ1RpbWUgUG9pbnQnKSsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvbWxdJykgKyAKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJIZXhDZXIiKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIpKSsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBULCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiUFJFIiwgIlBPU1QiKSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAoKICAKCiAgCiAgCiAgTEkuU3VtLm0gPC0gbWVsdChjb252VF9wYWlyZWQsIGlkLnZhcnMgPSBjKCdQaGVub3R5cGUnLCdUaW1lJyksIG1lYXN1cmUudmFycyA9IGMoJ1N1bS5NZW1icmFuZScpKQogIAogIGdncGxvdChmaWx0ZXIoTEkuU3VtLm0sICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT12YWx1ZSwgZmlsbD0gdmFyaWFibGUpKSArCiAgICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICAgIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0gJykgKyAKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJTVU0gTWVtYnJhbmUiKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIpKSsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiaGlnaCBjb252ZXJ0ZXIiLCAibG93IGNvbnZlcnRlciIpKSkrCiAgICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKICAKICBnZ3Bsb3QoZmlsdGVyKExJLlN1bS5tLCAhUGhlbm90eXBlPT0ibm90IGNsYXNzaWZpZWQiKSxhZXMoeD1UaW1lLCB5PXZhbHVlLCBmaWxsPSB2YXJpYWJsZSkpICsKICAgIGZhY2V0X2dyaWQoLn4gUGhlbm90eXBlKSArCiAgICB4bGFiICgnVGltZSBQb2ludCcpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0nKSArIAogICAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoInN1bSBtZW1icmFuZSIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFQsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkrCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCiAgCgogIAogIAogIAoKICBMSS5TdW0ucyA8LSBtZWx0KGNvbnZUX3BhaXJlZCwgaWQudmFycyA9IGMoJ1BoZW5vdHlwZScsJ1RpbWUnKSwgbWVhc3VyZS52YXJzID0gYygnU3VtLlN0b3JhZ2UnKSkKICAKICBnZ3Bsb3QoZmlsdGVyKExJLlN1bS5zLCAhUGhlbm90eXBlPT0ibm90IGNsYXNzaWZpZWQiKSxhZXMoeD1QaGVub3R5cGUsIHk9dmFsdWUsIGZpbGw9IHZhcmlhYmxlKSkgKwogICAgZmFjZXRfZ3JpZCgufiBUaW1lKSArCiAgICB4bGFiICgnQ29udmVydGVyIHR5cGUnKSsgeWxhYiAoJ0NvbmNlbnRyYXRpb24gW25tb2wvbWxdICcpICsgCiAgICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9YygiU1VNIFN0b3JhZ2UiKSwgdmFsdWVzID0gYygic3RlZWxibHVlMiIpKSsKICAgIGdlb21fYm94cGxvdCgpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLCBwYWlyZWQgPSBGLCBhZXMobGFiZWxzID0gLi5wLnNpZ25pZi4uKSwgY29tcGFyaXNvbnMgPWxpc3QoYygiaGlnaCBjb252ZXJ0ZXIiLCAibG93IGNvbnZlcnRlciIpKSkrCiAgICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKICAKICBnZ3Bsb3QoZmlsdGVyKExJLlN1bS5tLCAhUGhlbm90eXBlPT0ibm90IGNsYXNzaWZpZWQiKSxhZXMoeD1UaW1lLCB5PXZhbHVlLCBmaWxsPSB2YXJpYWJsZSkpICsKICAgIGZhY2V0X2dyaWQoLn4gUGhlbm90eXBlKSArCiAgICB4bGFiICgnVGltZSBQb2ludCcpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0nKSArIAogICAgc2NhbGVfZmlsbF9tYW51YWwobGFiZWxzPWMoInN1bSBtZW1icmFuZSIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IFQsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJQUkUiLCAiUE9TVCIpKSkrCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpCiAgCgogIAogIExJLlN1bS5sIDwtIG1lbHQoY29udlRfcGFpcmVkLCBpZC52YXJzID0gYygnUGhlbm90eXBlJywnVGltZScpLCBtZWFzdXJlLnZhcnMgPSBjKCdTdW0uTHlzbycpKQogIAogIGdncGxvdChmaWx0ZXIoTEkuU3VtLmwsICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVBoZW5vdHlwZSwgeT12YWx1ZSwgZmlsbD0gdmFyaWFibGUpKSArCiAgICBmYWNldF9ncmlkKC5+IFRpbWUpICsKICAgIHhsYWIgKCdDb252ZXJ0ZXIgdHlwZScpKyB5bGFiICgnQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0gJykgKyAKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxhYmVscz1jKCJTVU0gTHlzbyIpLCB2YWx1ZXMgPSBjKCJzdGVlbGJsdWUyIikpKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIHBhaXJlZCA9IEYsIGFlcyhsYWJlbHMgPSAuLnAuc2lnbmlmLi4pLCBjb21wYXJpc29ucyA9bGlzdChjKCJoaWdoIGNvbnZlcnRlciIsICJsb3cgY29udmVydGVyIikpKSsKICAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiKQogIAogIGdncGxvdChmaWx0ZXIoTEkuU3VtLm0sICFQaGVub3R5cGU9PSJub3QgY2xhc3NpZmllZCIpLGFlcyh4PVRpbWUsIHk9dmFsdWUsIGZpbGw9IHZhcmlhYmxlKSkgKwogICAgZmFjZXRfZ3JpZCgufiBQaGVub3R5cGUpICsKICAgIHhsYWIgKCdUaW1lIFBvaW50JykrIHlsYWIgKCdDb25jZW50cmF0aW9uIFtubW9sL21sXScpICsgCiAgICBzY2FsZV9maWxsX21hbnVhbChsYWJlbHM9Yygic3VtIG1lbWJyYW5lIiksIHZhbHVlcyA9IGMoInN0ZWVsYmx1ZTIiKSkrCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0IiwgcGFpcmVkID0gVCwgYWVzKGxhYmVscyA9IC4ucC5zaWduaWYuLiksIGNvbXBhcmlzb25zID1saXN0KGMoIlBSRSIsICJQT1NUIikpKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIikKICAKYGBgCgo2LjQgYWxwaGEtRGl2ZXJzaXTDpHRzYW5hbHlzZW4gbWl0IFNlcnVtbGlwaWRlCgpMYWRlbiwgZmlsdGVybiB1bmQgc3luY2hyb25pc2llcmVuIGRlciBNZXRhZGF0ZW4KCmBgYHtyfQptYXBfYWxwaGFkaXYgPC0gcmVhZC50YWJsZSgiL1VzZXJzL3N0dWRlbnQwNS9Eb3dubG9hZHMvbWVhbnNfYWxwaGFfZGl2LnR4dCIsIHNlcCA9ICdcdCcsIGNvbW1lbnQ9JycsaGVhZCA9IFRSVUUsIHJvdy5uYW1lcyA9IDEpCgpMSV9zZXJ1bSA8LSByZWFkLnRhYmxlKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMgemFobGVuLjEtMi50eHQiLCBzZXAgPSAnXHQnLCBjb21tZW50PScnLGhlYWQ9VCkKCkxJX3NlcnVtJFRpbWUgPC1mYWN0b3IoTElfc2VydW0kVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKCnJvdy5uYW1lcyhMSV9zZXJ1bSkgPC0gTElfc2VydW0kU2FtcGxlSUQgCgpyb3cubmFtZXMobWFwX2FscGhhZGl2KQoKY29tbW9uLmlkcy5TdCA8LSBpbnRlcnNlY3Qocm93bmFtZXMoTElfc2VydW0pLCByb3duYW1lcyhtYXBfYWxwaGFkaXYpKQoKY29tbW9uLmlkcy5TdCA8LSBpbnRlcnNlY3Qocm93Lm5hbWVzKExJX3NlcnVtKSwgcm93Lm5hbWVzKG1hcF9hbHBoYWRpdikpCgpMSV9zZXJ1bSA8LSBMSV9zZXJ1bVtjb21tb24uaWRzLlN0LF0KCm1hcF9hbHBoYWRpdiA8LSBtYXBfYWxwaGFkaXZbY29tbW9uLmlkcy5TdCxdCgpMSV9zZXJ1bSRTaGFubm9uIDwtIG1hcF9hbHBoYWRpdiRTaGFubm9uCgpMSV9zZXJ1bSRTaW1wc29uIDwtIG1hcF9hbHBoYWRpdiRTaW1wc29uCmBgYAoKTG9vcCBmw7xyIEtvcnJlbGF0aW9uc2FuYWx5c2Ugendpc2NoZW4gU2hhbm5vbi1JbmRleCB1bmQgU2VydW1saXBpZGVuCgpgYGB7cn0KY29ycl9jb2xuYW1lc19MSSA8LWNvbG5hbWVzKExJX3NlcnVtWyw3OjI2XSkKCmNvcnJfc3BlYXJtYW5fU2hhbm5vbl9MSSA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiB1bmlxdWUoY29ycl9jb2xuYW1lc19MSSkpIHsKCiAgdG1wIDwtIGZpbHRlcihMSV9zZXJ1bSwgIWlzLm5hKGkpKQoKICB4ID0gYXMubWF0cml4KGFzLmRhdGEuZnJhbWUobGFwcGx5KHRtcFssaV0sIGFzLm51bWVyaWMpKSkKCiAgeSA9IHQoYXMubWF0cml4KHRtcCRTaGFubm9uKSApCiAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQoKICB6ID0gYXMubWF0cml4KGFzLmRhdGEuZnJhbWUobGFwcGx5KHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldLGFzLm51bWVyaWMpKSkKICAKICB3ID0gdChhcy5tYXRyaXgoc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRTaGFubm9uKSkKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKCiAgciA9IGFzLm1hdHJpeChhcy5kYXRhLmZyYW1lKGxhcHBseShzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0sYXMubnVtZXJpYykpKQogIAogIHMgPSB0KGFzLm1hdHJpeChzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRTaGFubm9uKSkKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fU2hhbm5vbl9MSSkrMQogCiAgY29ycl9zcGVhcm1hbl9TaGFubm9uX0xJW25yb3csIkRpdiJdID0gIlNoYW5ub24iCiAgCiAgY29ycl9zcGVhcm1hbl9TaGFubm9uX0xJW25yb3csICJjb2x1bW4iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1NoYW5ub25fTElbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9TaGFubm9uX0xJW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9TaGFubm9uX0xJW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9TaGFubm9uX0xJW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1NoYW5ub25fTElbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fU2hhbm5vbl9MSVtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9TaGFubm9uX0xJJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9TaGFubm9uX0xJJHAudmFsdWUsbWV0aG9kID0gIkJIIiwgbiA9IDIwKQoKY29ycl9zcGVhcm1hbl9TaGFubm9uX0xJJHAuYWRqdXN0ZWRfUFJFIDwtcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9TaGFubm9uX0xJJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMjApCgpjb3JyX3NwZWFybWFuX1NoYW5ub25fTEkkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fU2hhbm5vbl9MSSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAyMCkKCmNvcnJfc3BlYXJtYW5fU2hhbm5vbl9MSSRwLmFkanVzdGVkX0ZVIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fU2hhbm5vbl9MSSRwLnZhbHVlX0ZVLCBtZXRob2QgPSAiQkgiLCBuID0gMjApCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1NoYW5ub25fTEksIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvc2VydW0gbGlwaWRzL2RpdmVyc2l0eS9MSS5TaGFubm9uLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmBgYAoKUGxvdHRlbiB2b24gS29ycmVsYXRpb25lbiB6d2lzY2hlbiBTaGFubm9uLUluZGV4IHVuZCBTZXJ1bWxpcGlkZW4KCmFsbGUgTGlwaWRlCgpgYGB7cn0KTElfc2VydW0ubWVsdCA8LSBtZWx0KExJX3NlcnVtLCBpZC52YXJzID0gYygnVGltZScsJ1NoYW5ub24nKSwgbWVhc3VyZS52YXJzID0gYyggJ1BDJywgJ1BDTycsICdTTScsICdQRScsICdQSScsJ1BFUCcsICdMUEMnLCAnQ0VSJywgJ0hleENlcicpKQpMSV9zZXJ1bS5tZWx0IDwtIGRwbHlyOjpyZW5hbWUoTElfc2VydW0ubWVsdCwgTEk9dmFyaWFibGUpCkxJX3NlcnVtLm1lbHQgPC0gZHBseXI6OnJlbmFtZShMSV9zZXJ1bS5tZWx0LCBDb25jZW50cmF0aW9uPXZhbHVlKQpMSV9zZXJ1bS5tZWx0LnByIDwtIHN1YnNldChmaWx0ZXIoTElfc2VydW0ubWVsdCwgIVRpbWUgPT0nUE9TVCcpKQpMSV9zZXJ1bS5tZWx0LnBvIDwtIHN1YnNldChmaWx0ZXIoTElfc2VydW0ubWVsdCwgIVRpbWUgPT0nUFJFJykpCgpnZ3NjYXR0ZXIoTElfc2VydW0ubWVsdC5wciwgeD0nQ29uY2VudHJhdGlvbicsIHk9J1NoYW5ub24nLGNvbG9yID0gJ0xJJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicsICdzdGVlbGJsdWUyJywgJ29yY2hpZDInLCAnZGVlcHBpbmsnLCAnYnJvd240JywgJ2RhcmtvcmFuZ2UxJywgJ2JsdWV2aW9sZXQnLCAnYXF1YW1hcmluZTMnKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLGNvci5jb2VmLmNvb3JkID0gYyggMTAwLCA3KSwgeGxhYj0gJ3NlcnVtIGxpcGlkIENvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdTaGFubm9uLUluZGV4JykrCiAgZmFjZXRfZ3JpZCgufiBMSSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIoTElfc2VydW0ubWVsdCwgeD0nQ29uY2VudHJhdGlvbicsIHk9J1NoYW5ub24nLGNvbG9yID0gJ0xJJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicsICdzdGVlbGJsdWUyJywgJ29yY2hpZDInLCAnZGVlcHBpbmsnLCAnYnJvd240JywgJ2RhcmtvcmFuZ2UxJywgJ2JsdWV2aW9sZXQnLCAnYXF1YW1hcmluZTMnKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnc2VydW0gbGlwaWQgQ29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKSsKICBmYWNldF9ncmlkKC5+IExJLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihMSV9zZXJ1bS5tZWx0LnBvLCB4PSdDb25jZW50cmF0aW9uJywgeT0nU2hhbm5vbicsY29sb3IgPSAnTEknLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJywgJ3N0ZWVsYmx1ZTInLCAnb3JjaGlkMicsICdkZWVwcGluaycsICdicm93bjQnLCAnZGFya29yYW5nZTEnLCAnYmx1ZXZpb2xldCcsICdhcXVhbWFyaW5lMycpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSxjb3IuY29lZi5jb29yZCA9IGMoTlVMTCwgTlVMTCksCiBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ3NlcnVtIGxpcGlkIENvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdTaGFubm9uLUluZGV4JykrCiAgZmFjZXRfZ3JpZCgufiBMSSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpgYGAKClN1bW1pZXJ0ZW4gTGlwaWRrb256ZW50cmF0aW9uZW4KCmBgYHtyfQoKTElfc2VydW0ubWVsdDEgPC0gbWVsdChMSV9zZXJ1bSwgaWQudmFycyA9IGMoJ1RpbWUnLCdTaGFubm9uJyksIG1lYXN1cmUudmFycyA9IGMoICdTdW0nLCAnU3VtLk1lbWJyYW5lJywnU3VtLlN0b3JhZ2UnLCAnU3VtLkx5c28nKSkKTElfc2VydW0ubWVsdDEgPC0gZHBseXI6OnJlbmFtZShMSV9zZXJ1bS5tZWx0MSwgTEk9dmFyaWFibGUpCkxJX3NlcnVtLm1lbHQxPC0gZHBseXI6OnJlbmFtZShMSV9zZXJ1bS5tZWx0MSwgQ29uY2VudHJhdGlvbj12YWx1ZSkKTElfc2VydW0ubWVsdDEucHIgPC0gc3Vic2V0KGZpbHRlcihMSV9zZXJ1bS5tZWx0MSwgIVRpbWUgPT0nUE9TVCcpKQpMSV9zZXJ1bS5tZWx0MS5wbyA8LSBzdWJzZXQoZmlsdGVyKExJX3NlcnVtLm1lbHQxLCAhVGltZSA9PSdQUkUnKSkKCmdnc2NhdHRlcihMSV9zZXJ1bS5tZWx0MS5wciwgeD0nQ29uY2VudHJhdGlvbicsIHk9J1NoYW5ub24nLGNvbG9yID0gJ0xJJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicsICdzdGVlbGJsdWUyJywgJ29yY2hpZDInKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLGNvci5jb2VmLmNvb3JkID0gYygwLCA3KSwgeGxhYj0gJ3N1bSBzZXJ1bSBsaXBpZCBDb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnU2hhbm5vbi1JbmRleCcpKwogIGZhY2V0X2dyaWQoLn4gTEksc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKExJX3NlcnVtLm1lbHQxLnBvLCB4PSdDb25jZW50cmF0aW9uJywgeT0nU2hhbm5vbicsY29sb3IgPSAnTEknLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJywgJ3N0ZWVsYmx1ZTInLCAnb3JjaGlkMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdzZXJ1bSBsaXBpZCBDb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnU2hhbm5vbi1JbmRleCcpKwogIGZhY2V0X2dyaWQoLn4gTEksc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKYGBgCgpMaXBpZHZlcmjDpGx0bmlzc2UKCmBgYHtyfQpMSV9zZXJ1bS5tZWx0MiA8LSBtZWx0KExJX3NlcnVtLCBpZC52YXJzID0gYygnVGltZScsJ1NoYW5ub24nKSwgbWVhc3VyZS52YXJzID0gYyggJ0xQQy5QQycsJ0NFUi5TTScsICdQQy5QRScpKQpMSV9zZXJ1bS5tZWx0MiA8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQyLCBMST12YXJpYWJsZSkKTElfc2VydW0ubWVsdDI8LSBkcGx5cjo6cmVuYW1lKExJX3NlcnVtLm1lbHQyLCBDb25jZW50cmF0aW9uPXZhbHVlKQpMSV9zZXJ1bS5tZWx0Mi5wciA8LSBzdWJzZXQoZmlsdGVyKExJX3NlcnVtLm1lbHQyLCAhVGltZSA9PSdQT1NUJykpCkxJX3NlcnVtLm1lbHQyLnBvIDwtIHN1YnNldChmaWx0ZXIoTElfc2VydW0ubWVsdDIsICFUaW1lID09J1BSRScpKQoKZ2dzY2F0dGVyKExJX3NlcnVtLm1lbHQyLnByLCB4PSdDb25jZW50cmF0aW9uJywgeT0nU2hhbm5vbicsY29sb3IgPSAnTEknLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJywgJ3N0ZWVsYmx1ZTInLCAnb3JjaGlkMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDAuMDMsIDcpLCB4bGFiPSAncmF0aW8gc2VydW0gbGlwaWRzJywgeWxhYiA9ICdTaGFubm9uLUluZGV4JykrCiAgZmFjZXRfZ3JpZCgufiBMSSxzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIoTElfc2VydW0ubWVsdDIucG8sIHg9J0NvbmNlbnRyYXRpb24nLCB5PSdTaGFubm9uJyxjb2xvciA9ICdMSScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nLCAnc3RlZWxibHVlMicsICdvcmNoaWQyJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoMC4wMywgNyksIHhsYWI9ICdyYXRpbyBzZXJ1bSBsaXBpZHMnLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKSsKICBmYWNldF9ncmlkKC5+IExJLHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihMSV9zZXJ1bSwgeD0nUEMuUEUnLCB5PSdTaGFubm9uJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicsICdzdGVlbGJsdWUyJywgJ29yY2hpZDInKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoNDAsIDcpLGNvci5jb2VmLnNpemUgPSA2LCB4bGFiPSAnUEMvUEUgc2VydW0gbGlwaWQgcmF0aW8nLCB5bGFiID0gJ1NoYW5ub24tSW5kZXgnKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKExJX3NlcnVtLCB4PSdQQy5QRScsIHk9J1NoYW5ub24nLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJywgJ3N0ZWVsYmx1ZTInLCAnb3JjaGlkMicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDQwLCA3KSxjb3IuY29lZi5zaXplID0gNiwgeGxhYj0gJ1BDL1BFIHNlcnVtIGxpcGlkIHJhdGlvJywgeWxhYiA9ICdTaGFubm9uLUluZGV4JykrCnRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQpgYGAKCkxvb3AgZsO8ciBLb3JyZWxhdGlvbnNhbmFseXNlIHp3aXNjaGVuIFNpbXBzb24tSW5kZXggdW5kIFNlcnVtbGlwaWRlbgoKYGBge3J9CmNvcnJfc3BlYXJtYW5fU2ltcHNvbl9MSSA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiB1bmlxdWUoY29ycl9jb2xuYW1lc19MSSkpIHsKIAogIHRtcCA8LSBmaWx0ZXIoTElfc2VydW0sICFpcy5uYShpKSkKCiAgeCA9IGFzLm1hdHJpeChhcy5kYXRhLmZyYW1lKGxhcHBseSh0bXBbLGldLCBhcy5udW1lcmljKSkpCgogIHkgPSB0KGFzLm1hdHJpeCh0bXAkU2ltcHNvbikpCgogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQoKICB6ID0gYXMubWF0cml4KGFzLmRhdGEuZnJhbWUobGFwcGx5KHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldLGFzLm51bWVyaWMpKSkKICAKICB3ID0gdChhcy5tYXRyaXggKHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkU2ltcHNvbikpCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKIAogIHIgPSBhcy5tYXRyaXgoYXMuZGF0YS5mcmFtZShsYXBwbHkoc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldLGFzLm51bWVyaWMpKSkKICAKICBzID0gdChhcy5tYXRyaXgoc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkU2ltcHNvbikpCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9TaW1wc29uX0xJKSsxCiAKICBjb3JyX3NwZWFybWFuX1NpbXBzb25fTElbbnJvdywiRGl2Il0gPSAiU2ltcHNvbiIKICAKICBjb3JyX3NwZWFybWFuX1NpbXBzb25fTElbbnJvdywgImNvbHVtbiJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fU2ltcHNvbl9MSVtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1NpbXBzb25fTElbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1NpbXBzb25fTElbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1NpbXBzb25fTElbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fU2ltcHNvbl9MSVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9TaW1wc29uX0xJW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAoKICAKfQoKY29ycl9zcGVhcm1hbl9TaW1wc29uX0xJJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9TaW1wc29uX0xJJHAudmFsdWUsbWV0aG9kID0gIkJIIiwgbiA9IDIwKQoKY29ycl9zcGVhcm1hbl9TaW1wc29uX0xJJHAuYWRqdXN0ZWRfUFJFIDwtcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9TaW1wc29uX0xJJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMjApCgpjb3JyX3NwZWFybWFuX1NpbXBzb25fTEkkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fU2ltcHNvbl9MSSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAyMCkKCmNvcnJfc3BlYXJtYW5fU2ltcHNvbl9MSSRwLmFkanVzdGVkX0ZVIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fU2ltcHNvbl9MSSRwLnZhbHVlX0ZVLCBtZXRob2QgPSAiQkgiLCBuID0gMjApCgoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9TaW1wc29uX0xJLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcy9kaXZlcnNpdHkvTEkuU2ltcHNvbi50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpgYGAKCi0+IGdsZWljaGVyIEVmZmVrdCB3aWUgYmVpIFNoYW5ub24tSW5kZXgKCjYuNSBLb3JyZWxhdGlvbnNhbmFseXNlbiB6d2lzY2hlbiBkZW0gcmVsYXRpdmVuIFZvcmtvbW1lbiB2b24gVGF4YSB1bmQgU2VydW1saXBpZGVuCgpMYWRlbiB1bmQgZmlsdGVybiBkZXIgTWV0YWRhdGVuCgpgYGB7cn0KCm1hcF9LRCA8LSByZWFkLnRhYmxlKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy90eHQgZGF0ZWllbiByL01hcHBpbmdmaWxlXzE2U3JSTkFfQkMyMi50eHQiLCBzZXAgPSdcdCcsIGNvbW1lbnQ9JycsIGhlYWQ9VCxyb3cubmFtZXMgPSAxKQoKcmVsYWIgPC0gcmVhZC50YWJsZSgiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvcmVsYXRpdmUgYWJ1bmRhbmNlL0w2X21ldGFkYXRhX3RheGFfc3RyaWN0X3N0b29sLnR4dCIsIHNlcCA9ICdcdCcsIGNvbW1lbnQ9JycsIGhlYWQ9VCkKCnJlbGFiX1BSRSA8LSBmaWx0ZXIocmVsYWIsIFRpbWUgPT0gIlBSRSIpCgpyZWxhYl9QT1NUIDwtIGZpbHRlcihyZWxhYiwgVGltZSA9PSAiUE9TVCIpCgpyZWxhYl9GVSA8LSBmaWx0ZXIocmVsYWIsIFRpbWUgPT0gIkZPTExPVy1VUCIpCgpyZWxhYl9tZWFuc19QUkUgPC0gYWdncmVnYXRlKHJlbGFiX1BSRVssIDEwOjkwXSwgbGlzdChyZWxhYl9QUkUkUHJvYmFuZCksIG1lYW4pCgpyZWxhYl9tZWFuc19QUkVbJ1RpbWUnXSA9ICdQUkUnCgpyZWxhYl9tZWFuc19QUkUgPC0gZHBseXI6OnJlbmFtZShyZWxhYl9tZWFuc19QUkUsIFByb2JhbmQ9R3JvdXAuMSkKCnJlbGFiX21lYW5zX1BPU1QgPC0gYWdncmVnYXRlKHJlbGFiX1BPU1RbLCAxMDo5MF0sIGxpc3QocmVsYWJfUE9TVCRQcm9iYW5kKSwgbWVhbikKCnJlbGFiX21lYW5zX1BPU1RbJ1RpbWUnXSA9ICdQT1NUJwoKcmVsYWJfbWVhbnNfUE9TVCA8LSBkcGx5cjo6cmVuYW1lKHJlbGFiX21lYW5zX1BPU1QsIFByb2JhbmQ9R3JvdXAuMSkKCnJlbGFiX21lYW5zX0ZVIDwtIGFnZ3JlZ2F0ZShyZWxhYl9GVVssIDEwOjkwXSwgbGlzdChyZWxhYl9GVSRQcm9iYW5kKSwgbWVhbikKCnJlbGFiX21lYW5zX0ZVWydUaW1lJ10gPSAnRk9MTE9XLVVQJwoKcmVsYWJfbWVhbnNfRlUgPC0gZHBseXI6OnJlbmFtZShyZWxhYl9tZWFuc19GVSwgUHJvYmFuZD1Hcm91cC4xKQoKcmVsYWJfbWVhbnMgPC0gZGF0YV9mcmFtZSgpCgpyZWxhYl9tZWFucyA8LSBiaW5kX3Jvd3MocmVsYWJfbWVhbnNfUFJFLCByZWxhYl9tZWFuc19QT1NULCByZWxhYl9tZWFuc19GVSkKCnJlbGFiX21lYW5zIDwtIHJlbGFiX21lYW5zWywgYygxLCA4MywgMjo4MildCgpyZWxhYl9tZWFuc19tZWx0IDwtIG1lbHQocmVsYWJfbWVhbnMsIGlkPWMoJ1Byb2JhbmQnLCAnVGltZScpKQoKcmVsYWJfbWVhbnNfbWVsdCA8LSBkcGx5cjo6cmVuYW1lKHJlbGFiX21lYW5zX21lbHQsIFRheGE9dmFyaWFibGUpCgpyZWxhYl9tZWFuc19tZWx0IDwtIGRwbHlyOjpyZW5hbWUocmVsYWJfbWVhbnNfbWVsdCwgUmVsYXRpdmVfQWJ1bmRhbmNlPXZhbHVlKQoKCnJlbGFiX3BoeWx1bSA8LSBzdWJzZXQocmVsYWJfbWVhbnNfbWVsdCwgIWdyZXBsKCJnX198Zl9ffG9fX3xjX18iLCByZWxhYl9tZWFuc19tZWx0JFRheGEpKQoKcmVsYWJfcGh5bHVtIDwtIHN1YnNldChyZWxhYl9waHlsdW0sICFncmVwbCgia19fQXJjaGFlYSIsIHJlbGFiX3BoeWx1bSRUYXhhKSkKCnJlbGFiX3BoeWx1bSRUaW1lIDwtIGZhY3RvcihyZWxhYl9waHlsdW0kVGltZSwgbGV2ZWxzPWMoJ1BSRScsJ1BPU1QnLCdGT0xMT1ctVVAnKSkKCnJlbGFiX3BoeWx1bV9zcHJlYWQgPC0gc3ByZWFkKHJlbGFiX3BoeWx1bSwgVGF4YSwgUmVsYXRpdmVfQWJ1bmRhbmNlLCBzZXAgPSBOVUxMKQoKCnJlbGFiX2dlbnVzIDwtIHN1YnNldChyZWxhYl9tZWFuc19tZWx0LCBncmVwbCgiZ19fIiwgcmVsYWJfbWVhbnNfbWVsdCRUYXhhKSkKCnJlbGFiX2dlbnVzIDwtIHN1YnNldChyZWxhYl9nZW51cywgIWdyZXBsKCJrX19BcmNoYWVhIiwgcmVsYWJfZ2VudXMkVGF4YSkpCgpyZWxhYl9nZW51cyRUaW1lIDwtIGZhY3RvcihyZWxhYl9nZW51cyRUaW1lLCBsZXZlbHMgPSBjKCdQUkUnLCdQT1NUJywnRk9MTE9XLVVQJykpCgpyZWxhYl9nZW51c19zcHJlYWQgPC0gc3ByZWFkKHJlbGFiX2dlbnVzLCBUYXhhLCBSZWxhdGl2ZV9BYnVuZGFuY2UsIHNlcCA9IE5VTEwpCgpgYGAKCkxhZGVuIGRlciBTZXJ1bWxpcGlkbWV0YWRhdGVuLCBTeW5jaG9uaXNpZXJlbiBkZXIgTWV0YWRhdGVuCgpgYGB7cn0KCkxJX3NlcnVtIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcyB6YWhsZW4uMS0yLnR4dCIsIHNlcCA9ICdcdCcsIGNvbW1lbnQ9JycsaGVhZD1UKQoKTElfc2VydW0kVGltZSA8LWZhY3RvcihMSV9zZXJ1bSRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKcmVsYWJfcGh5bHVtX0lEIDwtIHJlbGFiX3BoeWx1bV9zcHJlYWQKCnJlbGFiX3BoeWx1bV9JRCA8LSBtdXRhdGUocmVsYWJfcGh5bHVtX0lELCBTYW1wbGVJRCA9IHBhc3RlKFByb2JhbmQsIFRpbWUsc2VwPSIuIikpCgpyb3cubmFtZXMocmVsYWJfcGh5bHVtX0lEKSA8LSByZWxhYl9waHlsdW1fSUQkU2FtcGxlSUQKCnJlbGFiX2dlbnVzX0lEIDwtIHJlbGFiX2dlbnVzX3NwcmVhZAoKcmVsYWJfZ2VudXNfSUQgPC0gbXV0YXRlKHJlbGFiX2dlbnVzX0lELCBTYW1wbGVJRCA9IHBhc3RlKFByb2JhbmQsIFRpbWUsIHNlcCA9Ii4iKSkKCnJvdy5uYW1lcyhyZWxhYl9nZW51c19JRCkgPC0gcmVsYWJfZ2VudXNfSUQkU2FtcGxlSUQKCkxJX3NlcnVtIDwtIG11dGF0ZShMSV9zZXJ1bSwgU2FtcGxlSUQxID0gcGFzdGUoUHJvYmFuZCwgVGltZSwgc2VwID0gIi4iKSkKCnJvdy5uYW1lcyhMSV9zZXJ1bSkgPC0gTElfc2VydW0kU2FtcGxlSUQxCgpjb21tb24uaWRzLnJlbGFiIDwtIGludGVyc2VjdChyb3duYW1lcyhMSV9zZXJ1bSksIHJvd25hbWVzKHJlbGFiX3BoeWx1bV9JRCkpCgpMSV9zZXJ1bSA8LSBMSV9zZXJ1bVtjb21tb24uaWRzLnJlbGFiLF0KCnJlbGFiX3BoeWx1bV9JRCA8LSByZWxhYl9waHlsdW1fSURbY29tbW9uLmlkcy5yZWxhYixdCgpyZWxhYl9nZW51c19JRCA8LSByZWxhYl9nZW51c19JRFtjb21tb24uaWRzLnJlbGFiLF0KCmBgYAoKU3Vic2V0dGVuIGRlcyBQaHlsdW0tbGV2ZWxzLCBsb2ctVHJhbnNmb3JtYXRpb24gdW5kIGhpbnp1ZsO8aGVuIHZvbiBQc2V1ZG9jb3VudCAwLjAwMDAxCkZpbHRlcm4gbmFjaCBQcm9iZW4gbWl0IFBSRSB1bmQgUE9TVAoKYGBge3J9CgpwaHlsdW1fY29sbmFtZXMgPC0gY29sbmFtZXMocmVsYWJfcGh5bHVtX3NwcmVhZFssIGMoMzo4KV0pCgpyZWxhYl9waHlsdW1fSUQxIDwtIHJlbGFiX3BoeWx1bV9JRFssYygzOjgpXSArIDAuMDAwMDEKCnJlbGFiX3BoeWx1bV9JRF9sb2cgPC0gbG9nMTAocmVsYWJfcGh5bHVtX0lEX2xvZykKCnBoeWx1bV9MSSA8LSBjYmluZChyZWxhYl9waHlsdW1fSUQxLCBMSV9zZXJ1bVssIGMoMToyNyldKQoKcGh5bHVtX0xJJFByb2JhbmQKCnBoeWx1bV9MSSA8LSBzdWJzZXQoZmlsdGVyKHBoeWx1bV9MSSwgIVByb2JhbmQgPT0gJzMxS0UnKSkKcGh5bHVtX0xJIDwtIHN1YnNldChmaWx0ZXIocGh5bHVtX0xJLCAhUHJvYmFuZCA9PSAnNDVHTCcpKQpwaHlsdW1fTEkgPC0gc3Vic2V0KGZpbHRlcihwaHlsdW1fTEksICFQcm9iYW5kID09ICczNFdGJykpCnBoeWx1bV9MSSA8LSBzdWJzZXQoZmlsdGVyKHBoeWx1bV9MSSwgIVByb2JhbmQgPT0gJzU0U0wnKSkKcGh5bHVtX0xJIDwtIHN1YnNldChmaWx0ZXIocGh5bHVtX0xJLCAhUHJvYmFuZCA9PSAnNzRTQScpKQoKcGh5bHVtX0xJJFRpbWUgPC0gZmFjdG9yKHBoeWx1bV9MSSRUaW1lLCBsZXZlbHMgPSBjKCJQUkUiLCAiUE9TVCIpKQoKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBQaG9zcGhhdGlkeWxjaG9saW4gdW5kIHBoeWx1bS1sZXZlbAoKSW4gQXJiZWl0CgpgYGB7cn0KCmNvcnJfbWFwX3BoeWx1bV9QQyA8LSBmaWx0ZXIocGh5bHVtX0xJLCAhaXMubmEoUEMpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fUEMgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CiAgCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9waHlsdW1fUEMsICFpcy5uYShpKSkKIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRQQwogCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJFBDCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRQQwogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9QQykrMQoKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ1tucm93LCJGQSJdIDwtICJQQyIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ1tucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fUENbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ1tucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ1tucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fUENbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ1tucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ1tucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fUEMkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9QQyRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fUEMkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9QQywgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvcGh5bHVtL1BDLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdQQycsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1Bob3NwaGF0aWR5bGNob2xpbmtvbnplbnRyYXRpb25lbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZXMgVm9ya29tbWVuIHBfX0JhY3Rlcm9pZGV0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL1BDLlByb3Rlby5wZGYiLHdpZHRoPTgsIGhlaWdodD0xMCkKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCdza3libHVlJywgJ29yY2hpZCcpLHNpemUgPSAyLjUsIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoMTAwMCwgLTEuNSksIGNvci5jb2VmLnNpemUgPSA4LHhsYWI9ICdQaG9zcGhhdGlkeWxjaG9saW5rb256ZW50cmF0aW9uZW4gW25tb2wvbWxdJywgeWxhYiA9ICdSZWxhdGl2ZXMgVm9ya29tbWVuIHBfX1Byb3Rlb2JhY3RlcmlhIFslXScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmRldi5vZmYoKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoMTAwMCwgLTEuNSksIGNvci5jb2VmLnNpemUgPSA1LHhsYWI9ICdQQyBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCnRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQyBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fRmlybWljdXRlcyknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpgYGAKCkxvb3AgdW5kIFBsb3RzIEtvcnJlbGF0aW9uIHp3aXNjaGVuIFBob3NwaGF0aWR5bGNob2xpbi1QbGFzbWFsb2dlbiB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KCmNvcnJfbWFwX3BoeWx1bV9QQ08gPC0gZmlsdGVyKHBoeWx1bV9MSSwgIWlzLm5hKFBDTykpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ08gPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CgogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX1BDTywgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRQQ08KIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkUENPCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFBDTwogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ08pKzEKCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fUENPW25yb3csIkZBIl0gPC0gIlBDTyIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ09bbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDT1tucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDT1tucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ09bbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDT1tucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDT1tucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ09bbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ08kcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ08kcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDTyRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9QQ08kcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDTyRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fUENPJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9QaHlsdW1fUENPLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcy9waHlsdW0vUENPLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1BDTycsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1BDTycsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUENPJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1BDTycsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1RlbmVyaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUENPJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUENPJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpgYGAKCkxvb3AgdW5kIFBsb3RzIEtvcnJlbGF0aW9uIHp3aXNjaGVuIFBob3NwaGF0aWR5bGV0aGFub2xhbWluIHVuZCBwaHlsdW0tbGV2ZWwKCkluIEFyYmVpdApgYGB7cn0KCmNvcnJfbWFwX3BoeWx1bV9QRSA8LSBmaWx0ZXIocGh5bHVtX0xJLCAhaXMubmEoUEUpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fUEUgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CiAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9QRSwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRQRQogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRQRQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkUEUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fUEUpKzEKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QRVtucm93LCJGQSJdIDwtICJQRSIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QRVtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fUEVbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QRVtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QRVtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fUEVbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QRVtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QRVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1BFJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fUEUkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1BFJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BFJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9QRSRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fUEUkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9QaHlsdW1fUEUsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvc2VydW0gbGlwaWRzL3BoeWx1bS9QRS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdQRScsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPSBjKDEwLCAtMC45KSwgY29yLmNvZWYuc2l6ZSA9IDUsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdQRScsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgY29yLmNvZWYuY29vcmQgPSBjKDEwLCAtMC45KSwgY29yLmNvZWYuc2l6ZSA9IDUsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvUEUucHJvdGVvLnBkZiIsd2lkdGg9OC41LCBoZWlnaHQ9MTApCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1BFJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygnc2t5Ymx1ZScsICdvcmNoaWQnKSwgc2l6ZSA9IDIuNSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygxNSwgLTEuNSksIGNvci5jb2VmLnNpemUgPSA4LHhsYWI9ICdQaG9zcGhhdGlkeWxldGhhbm9sYW1pbmtvbnplbnRyYXRpb25lbiBbbm1vbC9tbF0nLCB5bGFiID0gJ1JlbGF0aXZlcyBWb3Jrb21tZW4gcF9fUHJvdGVvYmFjdGVyaWEgWyVdJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKZGV2Lm9mZigpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdQRScsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLGNvci5jb2VmLmNvb3JkID0gYygyMCwgLTEuNCksIGNvci5jb2VmLnNpemUgPSA1LCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdQRScsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdQRScsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdQRScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEUnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmBgYAoKTG9vcCB1bmQgUGxvdHMgS29ycmVsYXRpb24gendpc2NoZW4gU3BoaW5nb215ZWxpbiB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KCmNvcnJfbWFwX3BoeWx1bV9TTSA8LSBmaWx0ZXIocGh5bHVtX0xJLCAhaXMubmEoU00pKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fU00gPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CiAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9TTSwgIWlzLm5hKGkpKQogCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJFNNCiAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRTTQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkU00KICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fU00pKzEKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9TTVtucm93LCJGQSJdIDwtICJTTSIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9TTVtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU01bbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9TTVtucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9TTVtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU01bbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9TTVtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9TTVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1NNJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fU00kcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fU00kcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fU00kcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1NNJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9TTSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX1NNLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcy9waHlsdW0vU00udHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1NNJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU00gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJyxjb3IuY29lZi5jb29yZCA9IGMoMjAwLCAtMC45KSwgY29yLmNvZWYuc2l6ZSA9IDQsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1NNJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU00gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJyxjb3IuY29lZi5jb29yZCA9IGMoMjAwLCAtMC45KSwgY29yLmNvZWYuc2l6ZSA9IDQsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpK3RoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1NNJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdTTScsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdTTScsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1RlbmVyaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU00nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0Zpcm1pY3V0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdTTScsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBQaG9zcGhhdGlkeWxpbm9zaXRvbCB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KCmNvcnJfbWFwX3BoeWx1bV9QSSA8LSBmaWx0ZXIocGh5bHVtX0xJLCAhaXMubmEoUEkpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fUEkgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CiAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9QSSwgIWlzLm5hKGkpKQogCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJFBJCiAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRQSQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRQSQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9QSSkrMQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BJW25yb3csIkZBIl0gPC0gIlBJIgogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BJW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QSVtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BJW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BJW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QSVtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BJW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BJW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fUEkkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9QSSRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpIAoKY29ycl9zcGVhcm1hbl9QaHlsdW1fUEkkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fUEkkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1BJJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9QSSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9QSSwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvcGh5bHVtL1BJLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1BJJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU00gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdQSScsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdQSScsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdQSScsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdQSScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEknLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmBgYAoKTG9vcCB1bmQgUGxvdHMgS29ycmVsYXRpb24gendpc2NoZW4gUGhvc3BoYXRpZHlsZXRoYW5vbGFtaW4tUGxhc21hbG9nZW4gdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9Cgpjb3JyX21hcF9waHlsdW1fUEVQIDwtIGZpbHRlcihwaHlsdW1fTEksICFpcy5uYShQRVApKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fUEVQIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewoKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9QRVAsICFpcy5uYShpKSkKIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRQRVAKIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJFBFUAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQoKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFBFUAogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9QRVApKzEKIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BFUFtucm93LCJGQSJdIDwtICJQRVAiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fUEVQW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QRVBbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QRVBbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fUEVQW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QRVBbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QRVBbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fUEVQW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fUEVQJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fUEVQJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1BFUCRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9QRVAkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1BFUCRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fUEVQJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BFUCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvcGh5bHVtL1BFUC50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEVQJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEVQIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEVQJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1BFUCcsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdQRVAnLCB5PSdrX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEUgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1RlbmVyaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEVQJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEVQIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEVQJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpgYGAKCkxvb3AgdW5kIFBsb3RzIEtvcnJlbGF0aW9uIHp3aXNjaGVuIEx5c29waG9zcGhhdGlkeWxjaG9saW4gdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9Cgpjb3JyX21hcF9waHlsdW1fTFBDIDwtIGZpbHRlcihwaHlsdW1fTEksICFpcy5uYShMUEMpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fTFBDIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9waHlsdW1fTFBDLCAhaXMubmEoaSkpCiAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkTFBDCiAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJExQQwogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkTFBDCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fTFBDKSsxCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fTFBDW25yb3csIkZBIl0gPC0gIkxQQyIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9MUENbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0xQQ1tucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0xQQ1tucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9MUENbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0xQQ1tucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0xQQ1tucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9MUENbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9MUEMkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9MUEMkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0xQQyRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9MUEMkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0xQQyRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fTFBDJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX0xQQywgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvcGh5bHVtL0xQQy50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdMUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRVAgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0JhY3Rlcm9pZGV0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdMUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEUgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nTFBDJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J0xQQycsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdMUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMUEMgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0Zpcm1pY3V0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdMUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmBgYAoKTG9vcCB1bmQgUGxvdHMgS29ycmVsYXRpb24gendpc2NoZW4gQ2VyYW1pZCB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KCmNvcnJfbWFwX3BoeWx1bV9DRVIgPC0gZmlsdGVyKHBoeWx1bV9MSSwgIWlzLm5hKENFUikpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9DRVIgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CgogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX0NFUiwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRDRVIKIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJENFUgogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQoKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJENFUgogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCgogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX0NFUikrMQogCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fQ0VSW25yb3csIkZBIl0gPC0gIkNFUiIKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9DRVJbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0NFUltucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0NFUltucm93LCAicmhvIl0gPSByaG8KICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9DRVJbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0NFUltucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0NFUltucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9DRVJbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9DRVIkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9DRVIkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KSAKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0NFUiRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9DRVIkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0NFUiRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fQ0VSJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9QaHlsdW1fQ0VSLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcy9waHlsdW0vQ0VSLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J0NFUicsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0NlciBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCBjb3IuY29lZi5jb29yZCA9IGMoOCwgLTAuOSksIGNvci5jb2VmLnNpemUgPSA2LHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J0NFUicsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0NlciBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCBjb3IuY29lZi5jb29yZCA9IGMoOCwgLTAuOSksIGNvci5jb2VmLnNpemUgPSA2LHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIAogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J0NFUicsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdDZXIgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJyxjb3IuY29lZi5jb29yZCA9IGMoOCwgLTAuOSksIGNvci5jb2VmLnNpemUgPSA2LCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J0NFUicsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdDRVInLCB5PSdrX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEUgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1RlbmVyaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nQ0VSJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nQ0VSJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpgYGAKTG9vcCB1bmQgUGxvdHMgS29ycmVsYXRpb24gendpc2NoZW4gSGV4b3N5bGNlcmFtaWQgdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9Cgpjb3JyX21hcF9waHlsdW1fSGV4Q2VyIDwtIGZpbHRlcihwaHlsdW1fTEksICFpcy5uYShIZXhDZXIpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewoKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9IZXhDZXIsICFpcy5uYShpKSkKIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRIZXhDZXIKIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJEhleENlcgogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRIZXhDZXIKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQoKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9IZXhDZXIpKzEKIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0hleENlcltucm93LCJGQSJdIDwtICJIZXhDZXIiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9IZXhDZXJbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9IZXhDZXJbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9IZXhDZXJbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9IZXhDZXJbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkgCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9IZXhDZXIkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9IZXhDZXIkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX0hleENlciRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9IZXhDZXIsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvc2VydW0gbGlwaWRzL3BoeWx1bS9IZXhDZXIudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nSGV4Q2VyJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgbGFiZWwgPSAnUHJvYmFuZCcsCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnSGV4Q2VyIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdIZXhDZXInLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEUgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nSGV4Q2VyJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZXBfX1ZlcnJ1Y29taWNyb2JpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J0hleENlcicsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdIZXhDZXInLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMUEMgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0Zpcm1pY3V0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdIZXhDZXInLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmBgYAoKTG9vcCB1bmQgUGxvdHMgS29ycmVsYXRpb24gendpc2NoZW4gc3VtbWllcnRlbiBTZXJ1bWxpcGlkZW4gdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9Cgpjb3JyX21hcF9waHlsdW1fU3VtIDwtIGZpbHRlcihwaHlsdW1fTEksICFpcy5uYShTdW0pKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewoKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9TdW0sICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkU3VtCiAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkU3VtCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAKICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFN1bQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtKSsxCiAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW1bbnJvdywiRkEiXSA8LSAiU3VtIgogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bVtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bVtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bSRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bSRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW0kcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW0kcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW0sIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvc2VydW0gbGlwaWRzL3BoeWx1bS9TdW0udHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEVQIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1N1bScsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdTdW0nLCB5PSdrX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEUgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1RlbmVyaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpgYGAKCkxvb3AgdW5kIFBsb3RzIEtvcnJlbGF0aW9uIHp3aXNjaGVuIHN1bW1pZXJ0ZW4gTWVtYnJhbmxpcGlkZW4gdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9Cgpjb3JyX21hcF9waHlsdW1fU3VtLk1lbWJyYW5lIDwtIGZpbHRlcihwaHlsdW1fTEksICFpcy5uYShTdW0uTWVtYnJhbmUpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLk1lbWJyYW5lIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogIAogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX1N1bS5NZW1icmFuZSwgIWlzLm5hKGkpKQogCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJFN1bS5NZW1icmFuZQogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRTdW0uTWVtYnJhbmUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAKICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgCiAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFN1bS5NZW1icmFuZQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgCiAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW0uTWVtYnJhbmUpKzEKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW0uTWVtYnJhbmVbbnJvdywiRkEiXSA8LSAiU3VtLk1lbWJyYW5lIgogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5NZW1icmFuZVtucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLk1lbWJyYW5lW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLk1lbWJyYW5lW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5NZW1icmFuZVtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLk1lbWJyYW5lW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLk1lbWJyYW5lW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5NZW1icmFuZVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5NZW1icmFuZSRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5NZW1icmFuZSRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpIAoKY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLk1lbWJyYW5lJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5NZW1icmFuZSRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLk1lbWJyYW5lJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW0uTWVtYnJhbmUkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLk1lbWJyYW5lLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcy9waHlsdW0vU3VtLk1lbWJyYW5lLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1N1bS5NZW1icmFuZScsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFUCBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1N1bS5NZW1icmFuZScsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtbWFyaXplZCBtZW1icmFuZSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdTdW0uTWVtYnJhbmUnLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1N1bS5NZW1icmFuZScsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEUgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1RlbmVyaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtLk1lbWJyYW5lJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xQQyBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fRmlybWljdXRlcyknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1N1bS5NZW1icmFuZScsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmBgYAoKTG9vcCB1bmQgUGxvdHMgS29ycmVsYXRpb24gendpc2NoZW4gc3VtbWllcnRlbiBTdG9yYWdlbGlwaWRlbiB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KCmNvcnJfbWFwX3BoeWx1bV9TdW0uU3RvcmFnZSA8LSBmaWx0ZXIocGh5bHVtX0xJLCAhaXMubmEoU3VtLlN0b3JhZ2UpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLlN0b3JhZ2UgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CiAKICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX3BoeWx1bV9TdW0uU3RvcmFnZSwgIWlzLm5hKGkpKQogIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRTdW0uU3RvcmFnZQogIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRTdW0uU3RvcmFnZQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkU3VtLlN0b3JhZ2UKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5TdG9yYWdlKSsxCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLlN0b3JhZ2VbbnJvdywiRkEiXSA8LSAiU3VtLlN0b3JhZ2UiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLlN0b3JhZ2VbbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5TdG9yYWdlW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLlN0b3JhZ2VbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLlN0b3JhZ2VbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5TdG9yYWdlW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLlN0b3JhZ2VbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLlN0b3JhZ2VbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW0uU3RvcmFnZSRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5TdG9yYWdlJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkgCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW0uU3RvcmFnZSRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW0uU3RvcmFnZSRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLlN0b3JhZ2UkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5TdG9yYWdlJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5TdG9yYWdlLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcy9waHlsdW0vU3VtLlN0b3JhZ2UudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1N1bS5TdG9yYWdlJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ3N1bW1hcml6ZWQgc3RvcmFnZSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1N1bS5TdG9yYWdlJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdTdW0uU3RvcmFnZScsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ3N1bW1hcml6ZWQgc3RvcmFnZSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVmVycnVjb21pY3JvYmlhKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtLlN0b3JhZ2UnLCB5PSdrX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEUgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1RlbmVyaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtLlN0b3JhZ2UnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtLlN0b3JhZ2UnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQWN0aW5vYmFjdGVyaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBzdW1taWVydGVuIEx5c29saXBpZGVuIHVuZCBwaHlsdW0tbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9waHlsdW1fU3VtLkx5c28gPC0gZmlsdGVyKHBoeWx1bV9MSSwgIWlzLm5hKFN1bS5MeXNvKSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5MeXNvIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9waHlsdW1fU3VtLkx5c28sICFpcy5uYShpKSkKICAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkU3VtLkx5c28KICAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRTdW0uTHlzbwogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkU3VtLkx5c28KICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5MeXNvKSsxCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLkx5c29bbnJvdywiRkEiXSA8LSAiU3VtLkx5c28iCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLkx5c29bbnJvdywgIlBoeWx1bSJdID0gaQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5MeXNvW25yb3csICJwLnZhbHVlIl0gPSBwCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLkx5c29bbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLkx5c29bbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5MeXNvW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLkx5c29bbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLkx5c29bbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogIAp9Cgpjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW0uTHlzbyRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5MeXNvJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkgCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW0uTHlzbyRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9TdW0uTHlzbyRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fU3VtLkx5c28kcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5MeXNvJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX1N1bS5MeXNvLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcy9waHlsdW0vU3VtLkx5c28udHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtLkx5c28nLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnc3VtbWFyaXplZCBseXNvIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtLkx5c28nLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSxjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEUgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtLkx5c28nLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVmVycnVjb21pY3JvYmlhKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtLkx5c28nLCB5PSdrX19CYWN0ZXJpYS5wX19UZW5lcmljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEUgc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1RlbmVyaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nU3VtLkx5c28nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdzdW1tYXJpemVkIGx5c28gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0Zpcm1pY3V0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdTdW0uTHlzbycsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKYGBgCkxvb3AgdW5kIFBMb3RzIEtvcnJlbGF0aW9uIHp3aXNjaGVuIExQQy9QQy1WZXJow6RsdG5pcyB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KCmNvcnJfbWFwX3BoeWx1bV9MUEMuUEMgPC0gZmlsdGVyKHBoeWx1bV9MSSwgIWlzLm5hKExQQy5QQykpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9MUEMuUEMgPC0gZGF0YS5mcmFtZSgpCgpmb3IoIGkgaW4gcGh5bHVtX2NvbG5hbWVzKSB7CgogIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfcGh5bHVtX0xQQy5QQywgIWlzLm5hKGkpKQoKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkTFBDLlBDCiAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKIAogIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgCiAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKIAogIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogIAogIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJExQQy5QQwogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkTFBDLlBDCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAKICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX1BoeWx1bV9MUEMuUEMpKzEKIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0xQQy5QQ1tucm93LCJGQSJdIDwtICJMUEMuUEMiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fTFBDLlBDW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9MUEMuUENbbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9MUEMuUENbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fTFBDLlBDW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9MUEMuUENbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9MUEMuUENbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fTFBDLlBDW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fTFBDLlBDJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fTFBDLlBDJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkgCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9MUEMuUEMkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fTFBDLlBDJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9MUEMuUEMkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX0xQQy5QQyRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9MUEMuUEMsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvc2VydW0gbGlwaWRzL3BoeWx1bS9MUEMuUEMudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nTFBDLlBDJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDL1BDIHNlcnVtIGxpcGlkcyByYXRpbycsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nTFBDLlBDJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xQQy9QQyBzZXJ1bSBsaXBpZHMgcmF0aW8nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdMUEMuUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J0xQQy5QQycsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdMUEMuUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygwLjA0LCAtMC43NSkseGxhYj0gJ0xQQy9QQyBzZXJ1bSBsaXBpZHMgcmF0aW8nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fRmlybWljdXRlcyknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J0xQQy5QQycsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX0FjdGlub2JhY3RlcmlhKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKYGBgCgpMb29wIHVuZCBQTG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBDRVIvU00tVmVyaMOkbHRuaXMgdW5kIHBoeWx1bS1sZXZlbAoKYGBge3J9Cgpjb3JyX21hcF9waHlsdW1fQ0VSLlNNIDwtIGZpbHRlcihwaHlsdW1fTEksICFpcy5uYShDRVIuU00pKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fQ0VSLlNNIDwtIGRhdGEuZnJhbWUoKQoKZm9yKCBpIGluIHBoeWx1bV9jb2xuYW1lcykgewogCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9waHlsdW1fQ0VSLlNNLCAhaXMubmEoaSkpCiAKICB5ID0gdG1wWyxpXQogIAogIHggPSB0bXAkQ0VSLlNNCiAKICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQoKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRDRVIuU00KICAKICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgCiAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogIAogIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRDRVIuU00KICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX0NFUi5TTSkrMQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0NFUi5TTVtucm93LCJGQSJdIDwtICJDRVIuU00iCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fQ0VSLlNNW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9DRVIuU01bbnJvdywgInAudmFsdWUiXSA9IHAKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9DRVIuU01bbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fQ0VSLlNNW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9DRVIuU01bbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9DRVIuU01bbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fQ0VSLlNNW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fQ0VSLlNNJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fQ0VSLlNNJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0NFUi5TTSRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9DRVIuU00kcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0NFUi5TTSRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fQ0VSLlNNJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQoKCndyaXRlLnRhYmxlKGNvcnJfc3BlYXJtYW5fUGh5bHVtX0NFUi5TTSwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvcGh5bHVtL0NFUi5TTS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdDRVIuU00nLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDAuMDIsIC0wLjkpLCB4bGFiPSAnQ0VSL1NNIHNlcnVtIGxpcGlkcyByYXRpbycsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdDRVIuU00nLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSL1NNIHNlcnVtIGxpcGlkcyByYXRpbycsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19Qcm90ZW9iYWN0ZXJpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J0NFUi5TTScsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J0NFUi5TTScsIHk9J2tfX0JhY3RlcmlhLnBfX1RlbmVyaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdDRVIuU00nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygwLjAzLCAtMC43KSx4bGFiPSAnQ0VSL1NNIHNlcnVtIGxpcGlkcyByYXRpbycsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdDRVIuU00nLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmBgYAoKTG9vcCB1bmQgUExvdHMgS29ycmVsYXRpb24gendpc2NoZW4gSGV4Q0VSL0NFUi1WZXJow6RsdG5pcyB1bmQgcGh5bHVtLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfcGh5bHVtX0hleENlci5DRVIgPC0gZmlsdGVyKHBoeWx1bV9MSSwgIWlzLm5hKEhleENlci5DRVIpKQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyLkNFUiA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBwaHlsdW1fY29sbmFtZXMpIHsKCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9waHlsdW1fSGV4Q2VyLkNFUiwgIWlzLm5hKGkpKQogCiAgeSA9IHRtcFssaV0KICAKICB4ID0gdG1wJEhleENlci5DRVIKIAogIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogCiAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAKICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogCiAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgCiAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkSGV4Q2VyLkNFUgogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogCiAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogIAogIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRIZXhDZXIuQ0VSCiAgCiAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAKICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKIAogIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fUGh5bHVtX0hleENlci5DRVIpKzEKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9IZXhDZXIuQ0VSW25yb3csIkZBIl0gPC0gIkhleENlci5DRVIiCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyLkNFUltucm93LCAiUGh5bHVtIl0gPSBpCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyLkNFUltucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0hleENlci5DRVJbbnJvdywgInJobyJdID0gcmhvCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyLkNFUltucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyLkNFUltucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX0hleENlci5DRVJbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgCiAgY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyLkNFUltucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgCn0KCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0hleENlci5DRVIkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9IZXhDZXIuQ0VSJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkgCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9IZXhDZXIuQ0VSJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX0hleENlci5DRVIkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX0hleENlci5DRVIkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fUGh5bHVtX0hleENlci5DRVIkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCgoKd3JpdGUudGFibGUoY29ycl9zcGVhcm1hbl9QaHlsdW1fSGV4Q2VyLkNFUiwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvcGh5bHVtL0hleENlci5DRVIudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nSGV4Q2VyLkNFUicsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0NFUi9TTSBzZXJ1bSBsaXBpZHMgcmF0aW8nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fQmFjdGVyb2lkZXRlcyknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J0hleENlci5DRVInLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0NFUi9TTSBzZXJ1bSBsaXBpZHMgcmF0aW8nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fUHJvdGVvYmFjdGVyaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdIZXhDZXIuQ0VSJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19WZXJydWNvbWljcm9iaWEpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdIZXhDZXIuQ0VSJywgeT0na19fQmFjdGVyaWEucF9fVGVuZXJpY3V0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZHMgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgcF9fVGVuZXJpY3V0ZXMpJykrCiAgZmFjZXRfZ3JpZCgufiBUaW1lLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgpnZ3NjYXR0ZXIocGh5bHVtX0xJLCB4PSdIZXhDZXIuQ0VSJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSL1NNIHNlcnVtIGxpcGlkcyByYXRpbycsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nSGV4Q2VyLkNFUicsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmBgYAoKTG9vcCB1bmQgUExvdHMgS29ycmVsYXRpb24gendpc2NoZW4gUEMvUEUtVmVyaMOkbHRuaXMgdW5kIHBoeWx1bS1sZXZlbApJbiBBcmJlaXQKCmBgYHtyfQoKY29ycl9tYXBfcGh5bHVtX1BDLlBFIDwtIGZpbHRlcihwaHlsdW1fTEksICFpcy5uYShQQy5QRSkpCgpjb3JyX3NwZWFybWFuX1BoeWx1bV9QQy5QRSA8LSBkYXRhLmZyYW1lKCkKCmZvciggaSBpbiBwaHlsdW1fY29sbmFtZXMpIHsKCiAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9waHlsdW1fUEMuUEUsICFpcy5uYShpKSkKIAogIHkgPSB0bXBbLGldCiAgCiAgeCA9IHRtcCRQQy5QRQogCiAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAKICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogIAogIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAKICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAKICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRQQy5QRQogIAogIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAKICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgCiAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogIAogIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAKICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkUEMuUEUKICAKICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogIAogIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogIAogIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogCiAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9QaHlsdW1fUEMuUEUpKzEKIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDLlBFW25yb3csIkZBIl0gPC0gIlBDLlBFIgogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDLlBFW25yb3csICJQaHlsdW0iXSA9IGkKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QQy5QRVtucm93LCAicC52YWx1ZSJdID0gcAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDLlBFW25yb3csICJyaG8iXSA9IHJobwogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDLlBFW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAKICBjb3JyX3NwZWFybWFuX1BoeWx1bV9QQy5QRVtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDLlBFW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogIAogIGNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDLlBFW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAKfQoKY29ycl9zcGVhcm1hbl9QaHlsdW1fUEMuUEUkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9QQy5QRSRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpIAoKY29ycl9zcGVhcm1hbl9QaHlsdW1fUEMuUEUkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9QaHlsdW1fUEMuUEUkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCmNvcnJfc3BlYXJtYW5fUGh5bHVtX1BDLlBFJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX1BoeWx1bV9QQy5QRSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKCgp3cml0ZS50YWJsZShjb3JyX3NwZWFybWFuX1BoeWx1bV9QQy5QRSwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvcGh5bHVtL1BDLlBFLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1BDLlBFJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSL1NNIHNlcnVtIGxpcGlkcyByYXRpbycsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19CYWN0ZXJvaWRldGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEMuUEUnLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEMvUEUgc2VydW0gbGlwaWRzIHJhdGlvJyxjb3IuY29lZi5jb29yZCA9IGMoMzAsIC0xLjUpLCBjb3IuY29lZi5zaXplID0gNiwgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCnBkZigiL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvZmVydGlnZSBQbG90cy9QQy5QRS5Qcm90ZW8ucGRmIix3aWR0aD04LCBoZWlnaHQ9MTApCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1BDLlBFJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygnc2t5Ymx1ZScsICdvcmNoaWQnKSwgc2l6ZSA9IDIuNSwgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoMzAsIC0xLjcgKSwgY29yLmNvZWYuc2l6ZSA9IDcseGxhYj0gJ1BDL1BFIFZlcmjDpGx0bmlzJywgeWxhYiA9ICdSZWxhdGl2ZXMgVm9ya29tbWVuIHBfX1Byb3Rlb2JhY3RlcmlhIFslXScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmRldi5vZmYoKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEMuUEUnLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEMvUEUgc2VydW0gbGlwaWRzIHJhdGlvJyxjb3IuY29lZi5jb29yZCA9IGMoMzAsIC0xLjQpLCBjb3IuY29lZi5zaXplID0gNiwgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1Byb3Rlb2JhY3RlcmlhKScpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1BDLlBFJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWRzIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIHBfX1ZlcnJ1Y29taWNyb2JpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1BDLlBFJywgeT0na19fQmFjdGVyaWEucF9fVGVuZXJpY3V0ZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19UZW5lcmljdXRlcyknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmdnc2NhdHRlcihwaHlsdW1fTEksIHg9J1BDLlBFJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSL1NNIHNlcnVtIGxpcGlkcyByYXRpbycsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19GaXJtaWN1dGVzKScpKwogIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiwgY29sb3VyID0gImJsYWNrIikpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEMuUEUnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkcyBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBwX19BY3Rpbm9iYWN0ZXJpYSknKSsKICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCmBgYAoKS29ycmVsYXRpb25zYW5hbHlzZW4gendpc2NoZW4gR2VudXMtbGV2ZWwgdW5kIFNlcnVtbGlwaWRlbgoKU3Vic2V0dGVuIGRlcyBHZW51cy1sZXZlbCwgbG9nLVRyYW5zZm9ybWF0aW9uLCBoaW56dWbDvGdlbiB2b24gUHNldWRvY291bnQgMC4wMDAxCkZpbHRlcm4gbmFjaCBQUkUgdW5kIFBPU1QgUHJvYmVuCgpgYGB7cn0KCmdlbnVzX2NvbG5hbWVzIDwtIGNvbG5hbWVzKHJlbGFiX2dlbnVzX3NwcmVhZFssIGMoMzozMSldKQoKcmVsYWJfZ2VudXNfSUQxIDwtIHJlbGFiX2dlbnVzX0lEWyxjKDM6MzEpXSArIDAuMDAwMDEKCnJlbGFiX2dlbnVzX0lEX2xvZyA8LSBsb2cxMChyZWxhYl9nZW51c19JRF9sb2cpCgpnZW51c19MSSA8LSBjYmluZChyZWxhYl9nZW51c19JRDEsIExJX3NlcnVtKQoKIGdlbnVzX0xJIDwtIHN1YnNldChmaWx0ZXIoZ2VudXNfTEksICFQcm9iYW5kID09ICczMUtFJykpCiBnZW51c19MSSA8LSBzdWJzZXQoZmlsdGVyKGdlbnVzX0xJLCAhUHJvYmFuZCA9PSAnNDVHTCcpKQogZ2VudXNfTEkgPC0gc3Vic2V0KGZpbHRlcihnZW51c19MSSwgIVByb2JhbmQgPT0gJzM0V0YnKSkKIGdlbnVzX0xJIDwtIHN1YnNldChmaWx0ZXIoZ2VudXNfTEksICFQcm9iYW5kID09ICc1NFNMJykpCiBnZW51c19MSSA8LSBzdWJzZXQoZmlsdGVyKGdlbnVzX0xJLCAhUHJvYmFuZCA9PSAnNzRTQScpKQogCmdlbnVzX0xJJFRpbWUgPC0gZmFjdG9yKGdlbnVzX0xJJFRpbWUsIGxldmVscyA9IGMoIlBSRSIsICJQT1NUIikpCiAKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBQaG9zcGhhdGlkeWxjaG9saW4gdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfUEMgPC0gZmlsdGVyKGdlbnVzX0xJLCAhaXMubmEoUEMpKQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1BDIDwtIGRhdGEuZnJhbWUoKQogCiBmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAgCiAgIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfZ2VudXNfUEMsICFpcy5uYShpKSkKICAgCiAgIHkgPSB0bXBbLGldCiAgIAogICB4ID0gdG1wJFBDCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgIAogICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogICAKICAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgIAogICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRQQwogICAKICAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogICAKICAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogICAKICAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogICAKICAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFBDCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgIAogICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAgCiAgIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfUEMpKzEKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUENbbnJvdywiRkEiXSA9ICJQQyIKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUENbbnJvdywgIkdlbnVzIl0gPSBpCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BDW25yb3csICJwLnZhbHVlIl0gPSBwCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BDW25yb3csICJyaG8iXSA9IHJobwogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19QQ1tucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BDW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BDW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19QQ1tucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgIAogfQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1BDJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19QQyRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEMkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19QQyRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1BDJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1BDJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiB3cml0ZS50YWJsZSggY29ycl9zcGVhcm1hbl9nZW51c19QQywgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvZ2VudXMvUEMudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQogCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQQycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRmFlY2FsaWJhY3Rlcml1bScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BDJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCBjb3IuY29lZi5jb29yZCA9IGMoODAwLCAtMS42KSwgY29yLmNvZWYuc2l6ZSA9IDYseWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQ29wcm9jb2NjdXMnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIGNvci5jb2VmLmNvb3JkID0gYyg4MDAsIC0xLjYpLCBjb3IuY29lZi5zaXplID0gNix5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29wcm9jb2NjdXMnKSsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19CZXRhcHJvdGVvYmFjdGVyaWEub19fQnVya2hvbGRlcmlhbGVzLmZfX0FsY2FsaWdlbmFjZWFlLmdfX1N1dHRlcmVsbGEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsY29yLmNvZWYuY29vcmQgPSBjKDgwMCwgLTIpLCBjb3IuY29lZi5zaXplID0gNiwgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0wLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BDJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLGNvci5jb2VmLmNvb3JkID0gYyg4MDAsIC0yKSwgY29yLmNvZWYuc2l6ZSA9IDYsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0wLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BDJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BDJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQQycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19EaWFsaXN0ZXInLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBQaG9zcGhhdGlkeWxjaG9saW4tUGxhc21hbG9nZW4gdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfUENPIDwtIGZpbHRlcihnZW51c19MSSwgIWlzLm5hKFBDTykpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfUENPIDwtIGRhdGEuZnJhbWUoKQogCiBmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAgCiAgIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfZ2VudXNfUENPLCAhaXMubmEoaSkpCiAgIAogICB5ID0gdG1wWyxpXQogICAKICAgeCA9IHRtcCRQQ08KICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAgCiAgIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgIAogICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAgCiAgIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJFBDTwogICAKICAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogICAKICAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogICAKICAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogICAKICAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFBDTwogICAKICAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogICAKICAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgIAogICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX2dlbnVzX1BDTykrMQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19QQ09bbnJvdywiRkEiXSA9ICJQQ08iCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BDT1tucm93LCAiR2VudXMiXSA9IGkKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUENPW25yb3csICJwLnZhbHVlIl0gPSBwCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BDT1tucm93LCAicmhvIl0gPSByaG8KICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUENPW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUENPW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BDT1tucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUENPW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAgCiB9CiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfUENPJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19QQ08kcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1BDTyRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1BDTyRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1BDTyRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19QQ08kcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKCiB3cml0ZS50YWJsZSggY29ycl9zcGVhcm1hbl9nZW51c19QQ08sIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvc2VydW0gbGlwaWRzL2dlbnVzL1BDTy50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUENPJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQQ08nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUENPJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUENPIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUENPJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db3Byb2NvY2N1cycpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BDTycsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLmNfX0JldGFwcm90ZW9iYWN0ZXJpYS5vX19CdXJraG9sZGVyaWFsZXMuZl9fQWxjYWxpZ2VuYWNlYWUuZ19fU3V0dGVyZWxsYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUENPJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BDTycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUENPJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfXycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDTyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BDTycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19EaWFsaXN0ZXInLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQ08gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmBgYAoKTG9vcCB1bmQgUGxvdHMgS29ycmVsYXRpb24gendpc2NoZW4gU3BoaW5nb215ZWxpbiB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQogY29ycl9tYXBfZ2VudXNfU00gPC0gZmlsdGVyKGdlbnVzX0xJLCAhaXMubmEoU00pKQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1NNIDwtIGRhdGEuZnJhbWUoKQogCiBmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAgCiAgIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfZ2VudXNfU00sICFpcy5uYShpKSkKICAgCiAgIHkgPSB0bXBbLGldCiAgIAogICB4ID0gdG1wJFNNCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgIAogICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogICAKICAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgIAogICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRTTQogICAKICAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogICAKICAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogICAKICAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogICAKICAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFNNCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgIAogICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAgCiAgIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfU00pKzEKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU01bbnJvdywiRkEiXSA9ICJTTSIKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU01bbnJvdywgIkdlbnVzIl0gPSBpCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1NNW25yb3csICJwLnZhbHVlIl0gPSBwCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1NNW25yb3csICJyaG8iXSA9IHJobwogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TTVtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1NNW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1NNW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TTVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgIAogfQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1NNJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19TTSRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfU00kcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19TTSRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1NNJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1NNJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiAKIHdyaXRlLnRhYmxlKCBjb3JyX3NwZWFybWFuX2dlbnVzX1NNLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcy9nZW51cy9TTS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU00nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU00gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU00nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1NNIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0nKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTTScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Db3Byb2NvY2N1cycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1NNIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJyxjb3IuY29lZi5zaXplID0gNixjb3IuY29lZi5jb29yZCA9IGMoMjAwLCAtMS41KSwgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU00nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQ29wcm9jb2NjdXMnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTTSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsY29yLmNvZWYuc2l6ZSA9IDYsY29yLmNvZWYuY29vcmQgPSBjKDIwMCwgLTEuNSksIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db3Byb2NvY2N1cycpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU00nLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19BY3Rpbm9iYWN0ZXJpYS5vX19CaWZpZG9iYWN0ZXJpYWxlcy5mX19CaWZpZG9iYWN0ZXJpYWNlYWUuZ19fQmlmaWRvYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU00gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmlmaWRvYmFjdGVyaXVtJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTTScsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLmNfX0JldGFwcm90ZW9iYWN0ZXJpYS5vX19CdXJraG9sZGVyaWFsZXMuZl9fQWxjYWxpZ2VuYWNlYWUuZ19fU3V0dGVyZWxsYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1NNIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1NNJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTTSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU00nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTTSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTTScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19EaWFsaXN0ZXInLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTTSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1NNJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fVmVpbGxvbmVsbGFjZWFlLmdfX0RpYWxpc3RlcicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1NNIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBQaG9zcGhhdGlkeWxldGhhbm9sYW1pbiB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9nZW51c19QRSA8LSBmaWx0ZXIoZ2VudXNfTEksICFpcy5uYShQRSkpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEUgPC0gZGF0YS5mcmFtZSgpCiAKIGZvciggaSBpbiBnZW51c19jb2xuYW1lcykgewogICAKICAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19QRSwgIWlzLm5hKGkpKQogICAKICAgeSA9IHRtcFssaV0KICAgCiAgIHggPSB0bXAkUEUKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAgCiAgIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgIAogICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAgCiAgIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJFBFCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgIAogICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgIAogICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgIAogICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkUEUKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAgCiAgIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogICAKICAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19QRSkrMQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19QRVtucm93LCJGQSJdID0gIlBFIgogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19QRVtucm93LCAiR2VudXMiXSA9IGkKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEVbbnJvdywgInAudmFsdWUiXSA9IHAKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEVbbnJvdywgInJobyJdID0gcmhvCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BFW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEVbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEVbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BFW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAgCiB9CiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEUkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1BFJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19QRSRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1BFJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEUkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfUEUkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIAogd3JpdGUudGFibGUoIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEUsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvc2VydW0gbGlwaWRzL2dlbnVzL1BFLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BFJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BFJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQ29wcm9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db3Byb2NvY2N1cycpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEUnLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19CZXRhcHJvdGVvYmFjdGVyaWEub19fQnVya2hvbGRlcmlhbGVzLmZfX0FsY2FsaWdlbmFjZWFlLmdfX1N1dHRlcmVsbGEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQRScsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLmNfX0JldGFwcm90ZW9iYWN0ZXJpYS5vX19CdXJraG9sZGVyaWFsZXMuZl9fQWxjYWxpZ2VuYWNlYWUuZ19fU3V0dGVyZWxsYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQRScsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEUgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BFJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0RvcmVhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEUgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRG9yZWEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BFJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fVmVpbGxvbmVsbGFjZWFlLmdfX0RpYWxpc3RlcicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEUnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBQaG9zcGhhdGlkeWxpbm9zaXRvbCB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9nZW51c19QSSA8LSBmaWx0ZXIoZ2VudXNfTEksICFpcy5uYShQSSkpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEkgPC0gZGF0YS5mcmFtZSgpCiAKIGZvciggaSBpbiBnZW51c19jb2xuYW1lcykgewogICAKICAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19QSSwgIWlzLm5hKGkpKQogICAKICAgeSA9IHRtcFssaV0KICAgCiAgIHggPSB0bXAkUEkKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAgCiAgIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgIAogICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAgCiAgIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJFBJCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgIAogICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgIAogICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgIAogICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkUEkKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAgCiAgIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogICAKICAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19QSSkrMQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19QSVtucm93LCJGQSJdID0gIlBJIgogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19QSVtucm93LCAiR2VudXMiXSA9IGkKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUElbbnJvdywgInAudmFsdWUiXSA9IHAKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUElbbnJvdywgInJobyJdID0gcmhvCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BJW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUElbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUElbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BJW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAgCiB9CiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEkkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1BJJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19QSSRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1BJJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEkkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfUEkkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIAogd3JpdGUudGFibGUoIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEksIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvc2VydW0gbGlwaWRzL2dlbnVzL1BJLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQSScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQSSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQSScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEkgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRmFlY2FsaWJhY3Rlcml1bScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BJJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEkgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29wcm9jb2NjdXMnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQSScsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQSSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CaWZpZG9iYWN0ZXJpdW0nKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BJJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEkgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEknLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BJIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQSScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BJIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RvcmVhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEknLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19WZWlsbG9uZWxsYWNlYWUuZ19fRGlhbGlzdGVyJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEkgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BJJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXy5SdW1pbm9jb2NjdXMuJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEkgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQSScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BJIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEknLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQSSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBQaG9zcGhhdGlkeWxldGhhbm9sYW1pbi1QbGFzbWFsb2dlbiB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQoKIGNvcnJfbWFwX2dlbnVzX1BFUCA8LSBmaWx0ZXIoZ2VudXNfTEksICFpcy5uYShQRVApKQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1BFUCA8LSBkYXRhLmZyYW1lKCkKIAogZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgIAogICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX1BFUCwgIWlzLm5hKGkpKQogICAKICAgeSA9IHRtcFssaV0KICAgCiAgIHggPSB0bXAkUEVQCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgIAogICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogICAKICAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgIAogICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRQRVAKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAgCiAgIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAgCiAgIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAgCiAgIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRQRVAKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAgCiAgIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogICAKICAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19QRVApKzEKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEVQW25yb3csIkZBIl0gPSAiUEVQIgogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19QRVBbbnJvdywgIkdlbnVzIl0gPSBpCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BFUFtucm93LCAicC52YWx1ZSJdID0gcAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19QRVBbbnJvdywgInJobyJdID0gcmhvCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BFUFtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BFUFtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19QRVBbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BFUFtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgIAogfQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1BFUCRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfUEVQJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19QRVAkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19QRVAkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19QRVAkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfUEVQJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiAKIHdyaXRlLnRhYmxlKCBjb3JyX3NwZWFybWFuX2dlbnVzX1BFUCwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvZ2VudXMvUEVQLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BFUCcsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQRVAgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQRVAnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFUCBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEVQJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEVQIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQRVAnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19BY3Rpbm9iYWN0ZXJpYS5vX19CaWZpZG9iYWN0ZXJpYWxlcy5mX19CaWZpZG9iYWN0ZXJpYWNlYWUuZ19fQmlmaWRvYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEVQIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JpZmlkb2JhY3Rlcml1bScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEVQJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEVQIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQRVAnLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFUCBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEVQJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0RvcmVhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEVQIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RvcmVhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEVQJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fVmVpbGxvbmVsbGFjZWFlLmdfX0RpYWxpc3RlcicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFUCBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEVQJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfXycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFUCBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BFUCcsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFUCBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BFUCcsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19CYWN0ZXJvaWRhY2VhZS5nX19CYWN0ZXJvaWRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BFUCBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBMeXNvcGhvc3BoYXRpZHlsY2hvbGluIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX0xQQyA8LSBmaWx0ZXIoZ2VudXNfTEksICFpcy5uYShMUEMpKQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQyA8LSBkYXRhLmZyYW1lKCkKIAogZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgIAogICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX0xQQywgIWlzLm5hKGkpKQogICAKICAgeSA9IHRtcFssaV0KICAgCiAgIHggPSB0bXAkTFBDCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgIAogICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogICAKICAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgIAogICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRMUEMKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAgCiAgIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAgCiAgIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAgCiAgIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRMUEMKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAgCiAgIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogICAKICAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19MUEMpKzEKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfTFBDW25yb3csIkZBIl0gPSAiTFBDIgogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19MUENbbnJvdywgIkdlbnVzIl0gPSBpCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQ1tucm93LCAicC52YWx1ZSJdID0gcAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19MUENbbnJvdywgInJobyJdID0gcmhvCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQ1tucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQ1tucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19MUENbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQ1tucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgIAogfQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQyRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfTFBDJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19MUEMkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19MUEMkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19MUEMkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfTFBDJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiAKIHdyaXRlLnRhYmxlKCBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQywgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvZ2VudXMvTFBDLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdMUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nTFBDJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xQQyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nTFBDJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdMUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19BY3Rpbm9iYWN0ZXJpYS5vX19CaWZpZG9iYWN0ZXJpYWxlcy5mX19CaWZpZG9iYWN0ZXJpYWNlYWUuZ19fQmlmaWRvYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JpZmlkb2JhY3Rlcml1bScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nTFBDJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0xQQycsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdMUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRG9yZWEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdMUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19WZWlsbG9uZWxsYWNlYWUuZ19fRGlhbGlzdGVyJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nTFBDJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fVmVpbGxvbmVsbGFjZWFlLmdfX1BoYXNjb2xhcmN0b2JhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xQQyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0xQQycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX18nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdMUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdMUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmBgYAoKTG9vcCB1bmQgUGxvdHMgS29ycmVsYXRpb24gendpc2NoZW4gQ2VyYW1pZCB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9nZW51c19DRVIgPC0gZmlsdGVyKGdlbnVzX0xJLCAhaXMubmEoQ0VSKSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19DRVIgPC0gZGF0YS5mcmFtZSgpCiAKIGZvciggaSBpbiBnZW51c19jb2xuYW1lcykgewogICAKICAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19DRVIsICFpcy5uYShpKSkKICAgCiAgIHkgPSB0bXBbLGldCiAgIAogICB4ID0gdG1wJENFUgogICAKICAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogICAKICAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAgCiAgIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogICAKICAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkQ0VSCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgIAogICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgIAogICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgIAogICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkQ0VSCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgIAogICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAgCiAgIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfQ0VSKSsxCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0NFUltucm93LCJGQSJdID0gIkNFUiIKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfQ0VSW25yb3csICJHZW51cyJdID0gaQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19DRVJbbnJvdywgInAudmFsdWUiXSA9IHAKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfQ0VSW25yb3csICJyaG8iXSA9IHJobwogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19DRVJbbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19DRVJbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfQ0VSW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19DRVJbbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogICAKIH0KIAogY29ycl9zcGVhcm1hbl9nZW51c19DRVIkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX0NFUiRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfQ0VSJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfQ0VSJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfQ0VSJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX0NFUiRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogCiB3cml0ZS50YWJsZSggY29ycl9zcGVhcm1hbl9nZW51c19DRVIsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvc2VydW0gbGlwaWRzL2dlbnVzL0NFUi50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCiAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdDRVInLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nQ0VSJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0NFUiBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nQ0VSJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nQ0VSJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0NFUiBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CaWZpZG9iYWN0ZXJpdW0nKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0NFUicsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLmNfX0JldGFwcm90ZW9iYWN0ZXJpYS5vX19CdXJraG9sZGVyaWFsZXMuZl9fQWxjYWxpZ2VuYWNlYWUuZ19fU3V0dGVyZWxsYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0NFUiBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nQ0VSJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdDRVIgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0NFUicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0NFUiBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Eb3JlYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0NFUicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19EaWFsaXN0ZXInLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdDRVIgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0NFUicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19QaGFzY29sYXJjdG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdDRVIgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdDRVInLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nQ0VSJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0RvcmVhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nQ0VSJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX0JhY3Rlcm9pZGFjZWFlLmdfX0JhY3Rlcm9pZGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgpgYGAKCkxvb3AgdW5kIFBsb3RzIEtvcnJlbGF0aW9uIHp3aXNjaGVuIEhleG9zeWxjZXJhbWlkIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX0hleENlciA8LSBmaWx0ZXIoZ2VudXNfTEksICFpcy5uYShIZXhDZXIpKQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX0hleENlciA8LSBkYXRhLmZyYW1lKCkKIAogZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgIAogICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX0hleENlciwgIWlzLm5hKGkpKQogICAKICAgeSA9IHRtcFssaV0KICAgCiAgIHggPSB0bXAkSGV4Q2VyCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgIAogICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogICAKICAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgIAogICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRIZXhDZXIKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAgCiAgIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAgCiAgIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAgCiAgIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRIZXhDZXIKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAgCiAgIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogICAKICAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXIpKzEKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfSGV4Q2VyW25yb3csIkZBIl0gPSAiSGV4Q2VyIgogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXJbbnJvdywgIkdlbnVzIl0gPSBpCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0hleENlcltucm93LCAicC52YWx1ZSJdID0gcAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXJbbnJvdywgInJobyJdID0gcmhvCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0hleENlcltucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0hleENlcltucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXJbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0hleENlcltucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgIAogfQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX0hleENlciRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfSGV4Q2VyJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXIkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXIkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXIkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfSGV4Q2VyJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiAKIHdyaXRlLnRhYmxlKCBjb3JyX3NwZWFybWFuX2dlbnVzX0hleENlciwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvZ2VudXMvSGV4Q2VyLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nSGV4Q2VyJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0hleENlciBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0hleENlcicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJyxjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdIZXhDZXIgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRmFlY2FsaWJhY3Rlcml1bScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0hleENlcicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Db3Byb2NvY2N1cycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0hleENlciBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db3Byb2NvY2N1cycpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0hleENlcicsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdIZXhDZXIgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmlmaWRvYmFjdGVyaXVtJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdIZXhDZXInLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19CZXRhcHJvdGVvYmFjdGVyaWEub19fQnVya2hvbGRlcmlhbGVzLmZfX0FsY2FsaWdlbmFjZWFlLmdfX1N1dHRlcmVsbGEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdIZXhDZXIgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nSGV4Q2VyJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdIZXhDZXIgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0hleENlcicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0hleENlciBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Eb3JlYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nSGV4Q2VyJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fVmVpbGxvbmVsbGFjZWFlLmdfX0RpYWxpc3RlcicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0hleENlciBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nSGV4Q2VyJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fVmVpbGxvbmVsbGFjZWFlLmdfX1BoYXNjb2xhcmN0b2JhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0hleENlciBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0hleENlcicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX18uUnVtaW5vY29jY3VzLicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0hleENlciBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0hleENlcicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0hleENlciBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0hleENlcicsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19CYWN0ZXJvaWRhY2VhZS5nX19CYWN0ZXJvaWRlcycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0hleENlciBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0hleENlcicsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19QcmV2b3RlbGxhY2VhZS5nX19QcmV2b3RlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCBsYWJlbD0gJ1Byb2JhbmQnLAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdIZXhDZXIgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUHJldm90ZWxsYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBzdW1taWVydGVuIFNlcnVtbGlwaWRlbiB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9nZW51c19TdW0gPC0gZmlsdGVyKGdlbnVzX0xJLCAhaXMubmEoU3VtKSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19TdW0gPC0gZGF0YS5mcmFtZSgpCiAKIGZvciggaSBpbiBnZW51c19jb2xuYW1lcykgewogICAKICAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19TdW0sICFpcy5uYShpKSkKICAgCiAgIHkgPSB0bXBbLGldCiAgIAogICB4ID0gdG1wJFN1bQogICAKICAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogICAKICAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAgCiAgIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogICAKICAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkU3VtCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgIAogICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgIAogICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgIAogICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkU3VtCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgIAogICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAgCiAgIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtKSsxCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1N1bVtucm93LCJGQSJdID0gIlN1bSIKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtW25yb3csICJHZW51cyJdID0gaQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TdW1bbnJvdywgInAudmFsdWUiXSA9IHAKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtW25yb3csICJyaG8iXSA9IHJobwogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TdW1bbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TdW1bbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TdW1bbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogICAKIH0KIAogY29ycl9zcGVhcm1hbl9nZW51c19TdW0kcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1N1bSRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1N1bSRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogCiB3cml0ZS50YWJsZSggY29ycl9zcGVhcm1hbl9nZW51c19TdW0sIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvc2VydW0gbGlwaWRzL2dlbnVzL1N1bS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCiAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0nKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQ29wcm9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29wcm9jb2NjdXMnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bScsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmlmaWRvYmFjdGVyaXVtJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0nLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19CZXRhcHJvdGVvYmFjdGVyaWEub19fQnVya2hvbGRlcmlhbGVzLmZfX0FsY2FsaWdlbmFjZWFlLmdfX1N1dHRlcmVsbGEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1N1bSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Eb3JlYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19EaWFsaXN0ZXInLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19WZWlsbG9uZWxsYWNlYWUuZ19fUGhhc2NvbGFyY3RvYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXy5SdW1pbm9jb2NjdXMuJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0RvcmVhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX0JhY3Rlcm9pZGFjZWFlLmdfX0JhY3Rlcm9pZGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0VyeXNpcGVsb3RyaWNoaS5vX19FcnlzaXBlbG90cmljaGFsZXMuZl9fRXJ5c2lwZWxvdHJpY2hhY2VhZS5nX18uRXViYWN0ZXJpdW0uJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgpgYGAKCkxvb3AgdW5kIFBsb3RzIEtvcnJlbGF0aW9uIHp3aXNjaGVuIHN1bW1pZXJ0ZW4gTWVtYnJhbmxpcGlkZW4gdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KY29ycl9tYXBfZ2VudXNfU3VtLk1lbWJyYW5lIDwtIGZpbHRlcihnZW51c19MSSwgIWlzLm5hKFN1bS5NZW1icmFuZSkpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLk1lbWJyYW5lIDwtIGRhdGEuZnJhbWUoKQogCiBmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAgCiAgIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfZ2VudXNfU3VtLk1lbWJyYW5lLCAhaXMubmEoaSkpCiAgIAogICB5ID0gdG1wWyxpXQogICAKICAgeCA9IHRtcCRTdW0uTWVtYnJhbmUKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAgCiAgIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgIAogICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAgCiAgIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJFN1bS5NZW1icmFuZQogICAKICAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogICAKICAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogICAKICAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogICAKICAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFN1bS5NZW1icmFuZQogICAKICAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogICAKICAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgIAogICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5NZW1icmFuZSkrMQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TdW0uTWVtYnJhbmVbbnJvdywiRkEiXSA9ICJTdW0uTWVtYnJhbmUiCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5NZW1icmFuZVtucm93LCAiR2VudXMiXSA9IGkKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLk1lbWJyYW5lW25yb3csICJwLnZhbHVlIl0gPSBwCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5NZW1icmFuZVtucm93LCAicmhvIl0gPSByaG8KICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLk1lbWJyYW5lW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLk1lbWJyYW5lW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5NZW1icmFuZVtucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLk1lbWJyYW5lW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAgCiB9CiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLk1lbWJyYW5lJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19TdW0uTWVtYnJhbmUkcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5NZW1icmFuZSRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5NZW1icmFuZSRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5NZW1icmFuZSRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19TdW0uTWVtYnJhbmUkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIAogd3JpdGUudGFibGUoIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLk1lbWJyYW5lLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcy9nZW51cy9TdW0uTWVtYnJhbmUudHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQogCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uTWVtYnJhbmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLk1lbWJyYW5lIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLk1lbWJyYW5lJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1N1bS5NZW1icmFuZSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLk1lbWJyYW5lJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLk1lbWJyYW5lIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uTWVtYnJhbmUnLCB5PSdrX19CYWN0ZXJpYS5wX19BY3Rpbm9iYWN0ZXJpYS5jX19BY3Rpbm9iYWN0ZXJpYS5vX19CaWZpZG9iYWN0ZXJpYWxlcy5mX19CaWZpZG9iYWN0ZXJpYWNlYWUuZ19fQmlmaWRvYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLk1lbWJyYW5lIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JpZmlkb2JhY3Rlcml1bScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLk1lbWJyYW5lJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLk1lbWJyYW5lIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bS5NZW1icmFuZScsIHk9J2tfX0JhY3RlcmlhLnBfX1ZlcnJ1Y29taWNyb2JpYS5jX19WZXJydWNvbWljcm9iaWFlLm9fX1ZlcnJ1Y29taWNyb2JpYWxlcy5mX19WZXJydWNvbWljcm9iaWFjZWFlLmdfX0Fra2VybWFuc2lhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLk1lbWJyYW5lIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uTWVtYnJhbmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uTWVtYnJhbmUgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRG9yZWEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bS5NZW1icmFuZScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19EaWFsaXN0ZXInLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uTWVtYnJhbmUgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bS5NZW1icmFuZScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19QaGFzY29sYXJjdG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uTWVtYnJhbmUgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uTWVtYnJhbmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fLlJ1bWlub2NvY2N1cy4nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uTWVtYnJhbmUgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uTWVtYnJhbmUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uTWVtYnJhbmUgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uTWVtYnJhbmUnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uTWVtYnJhbmUgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bS5NZW1icmFuZScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19EaWFsaXN0ZXInLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uTWVtYnJhbmUgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmBgYAoKTG9vcCB1bmQgUGxvdHMgS29ycmVsYXRpb24gendpc2NoZW4gc3VtbWllcnRlbiBTdG9yYWdlbGlwaWRlbiB1bmQgZ2VudXMtbGV2ZWwKCmBgYHtyfQpjb3JyX21hcF9nZW51c19TdW0uU3RvcmFnZSA8LSBmaWx0ZXIoZ2VudXNfTEksICFpcy5uYShTdW0uU3RvcmFnZSkpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLlN0b3JhZ2UgPC0gZGF0YS5mcmFtZSgpCiAKIGZvciggaSBpbiBnZW51c19jb2xuYW1lcykgewogICAKICAgdG1wIDwtIGZpbHRlcihjb3JyX21hcF9nZW51c19TdW0uU3RvcmFnZSwgIWlzLm5hKGkpKQogICAKICAgeSA9IHRtcFssaV0KICAgCiAgIHggPSB0bXAkU3VtLlN0b3JhZ2UKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAgCiAgIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgIAogICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAgCiAgIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJFN1bS5TdG9yYWdlCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbl9QUkUgPC0gY29yLnRlc3QoeiwgdywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJGVzdGltYXRlCiAgIAogICBwX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRwLnZhbHVlCiAgIAogICByID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSlbLGldCiAgIAogICBzID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBPU1QiKSkkU3VtLlN0b3JhZ2UKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAgCiAgIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogICAKICAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19TdW0uU3RvcmFnZSkrMQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TdW0uU3RvcmFnZVtucm93LCJGQSJdID0gIlN1bS5TdG9yYWdlIgogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TdW0uU3RvcmFnZVtucm93LCAiR2VudXMiXSA9IGkKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLlN0b3JhZ2VbbnJvdywgInAudmFsdWUiXSA9IHAKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLlN0b3JhZ2VbbnJvdywgInJobyJdID0gcmhvCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5TdG9yYWdlW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLlN0b3JhZ2VbbnJvdywgInJob19QUkUiXSA9IHJob19QUkUKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLlN0b3JhZ2VbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5TdG9yYWdlW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAgCiB9CiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLlN0b3JhZ2UkcC5hZGp1c3RlZCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5TdG9yYWdlJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19TdW0uU3RvcmFnZSRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5TdG9yYWdlJHAudmFsdWVfUFJFLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLlN0b3JhZ2UkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLlN0b3JhZ2UkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIAogd3JpdGUudGFibGUoIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLlN0b3JhZ2UsIGZpbGUgPSAnL1VzZXJzL3N0dWRlbnQwNS9Eb2N1bWVudHMvc2VydW0gbGlwaWRzL2dlbnVzL1N1bS5TdG9yYWdlLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bS5TdG9yYWdlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1N1bS5TdG9yYWdlIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLlN0b3JhZ2UnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLlN0b3JhZ2Ugc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRmFlY2FsaWJhY3Rlcml1bScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLlN0b3JhZ2UnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fQ29wcm9jb2NjdXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uU3RvcmFnZSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db3Byb2NvY2N1cycpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bS5TdG9yYWdlJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1N1bS5TdG9yYWdlIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JpZmlkb2JhY3Rlcml1bScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLlN0b3JhZ2UnLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19CZXRhcHJvdGVvYmFjdGVyaWEub19fQnVya2hvbGRlcmlhbGVzLmZfX0FsY2FsaWdlbmFjZWFlLmdfX1N1dHRlcmVsbGEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uU3RvcmFnZSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLlN0b3JhZ2UnLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1N1bS5TdG9yYWdlIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uU3RvcmFnZScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1N1bS5TdG9yYWdlIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RvcmVhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLlN0b3JhZ2UnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19WZWlsbG9uZWxsYWNlYWUuZ19fRGlhbGlzdGVyJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLlN0b3JhZ2Ugc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uU3RvcmFnZScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19QaGFzY29sYXJjdG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uU3RvcmFnZSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bS5TdG9yYWdlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXy5SdW1pbm9jb2NjdXMuJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLlN0b3JhZ2Ugc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uU3RvcmFnZScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1N1bS5TdG9yYWdlIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLlN0b3JhZ2UnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uU3RvcmFnZSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bS5TdG9yYWdlJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fVmVpbGxvbmVsbGFjZWFlLmdfX0RpYWxpc3RlcicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1N1bS5TdG9yYWdlIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBzdW1taWVydGVuIEx5c29saXBpZGVuIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX1N1bS5MeXNvIDwtIGZpbHRlcihnZW51c19MSSwgIWlzLm5hKFN1bS5MeXNvKSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19TdW0uTHlzbyA8LSBkYXRhLmZyYW1lKCkKIAogZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgIAogICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX1N1bS5MeXNvLCAhaXMubmEoaSkpCiAgIAogICB5ID0gdG1wWyxpXQogICAKICAgeCA9IHRtcCRTdW0uTHlzbwogICAKICAgdG1wX2NvcnJfc3BlYXJtYW4gPC0gY29yLnRlc3QoeCwgeSwgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG8gPSB0bXBfY29ycl9zcGVhcm1hbiRlc3RpbWF0ZQogICAKICAgcCA9IHRtcF9jb3JyX3NwZWFybWFuJHAudmFsdWUKICAgCiAgIHogPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpWyxpXQogICAKICAgdyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSkkU3VtLkx5c28KICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAgCiAgIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAgCiAgIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAgCiAgIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRTdW0uTHlzbwogICAKICAgdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCA8LSBjb3IudGVzdChyLCBzLCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJob19QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRlc3RpbWF0ZQogICAKICAgcF9QT1NUID0gdG1wX2NvcnJfc3BlYXJtYW5fUE9TVCRwLnZhbHVlCiAgIAogICBucm93ID0gbnJvdyhjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5MeXNvKSsxCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5MeXNvW25yb3csIkZBIl0gPSAiU3VtLkx5c28iCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5MeXNvW25yb3csICJHZW51cyJdID0gaQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TdW0uTHlzb1tucm93LCAicC52YWx1ZSJdID0gcAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TdW0uTHlzb1tucm93LCAicmhvIl0gPSByaG8KICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLkx5c29bbnJvdywgInAudmFsdWVfUFJFIl0gPSBwX1BSRQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TdW0uTHlzb1tucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19TdW0uTHlzb1tucm93LCAicC52YWx1ZV9QT1NUIl0gPSBwX1BPU1QKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLkx5c29bbnJvdywgInJob19QT1NUIl0gPSByaG9fUE9TVAogICAKIH0KIAogY29ycl9zcGVhcm1hbl9nZW51c19TdW0uTHlzbyRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLkx5c28kcC52YWx1ZSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1N1bS5MeXNvJHAuYWRqdXN0ZWRfUFJFIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfU3VtLkx5c28kcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19TdW0uTHlzbyRwLmFkanVzdGVkX1BPU1QgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19TdW0uTHlzbyRwLnZhbHVlX1BPU1QsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogCiB3cml0ZS50YWJsZSggY29ycl9zcGVhcm1hbl9nZW51c19TdW0uTHlzbywgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvZ2VudXMvU3VtLkx5c28udHh0Jywgc2VwID0iXHQiLCBjb2wubmFtZXMgPSBUUlVFLHJvdy5uYW1lcyA9IEZBTFNFKQoKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLkx5c28nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLkx5c28gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fT3NjaWxsb3NwaXJhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uTHlzbycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJyxjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsY29yLmNvZWYuY29vcmQgPSBjKDUwLCAtMS41KSwgeGxhYj0gJ1N1bS5MeXNvIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0nKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uTHlzbycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Db3Byb2NvY2N1cycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1N1bS5MeXNvIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uTHlzbycsIHk9J2tfX0JhY3RlcmlhLnBfX0FjdGlub2JhY3RlcmlhLmNfX0FjdGlub2JhY3RlcmlhLm9fX0JpZmlkb2JhY3RlcmlhbGVzLmZfX0JpZmlkb2JhY3RlcmlhY2VhZS5nX19CaWZpZG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uTHlzbyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CaWZpZG9iYWN0ZXJpdW0nKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bS5MeXNvJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLkx5c28gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bS5MeXNvJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uTHlzbyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLkx5c28nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uTHlzbyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Eb3JlYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLkx5c28nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19WZWlsbG9uZWxsYWNlYWUuZ19fRGlhbGlzdGVyJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLkx5c28gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uTHlzbycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19QaGFzY29sYXJjdG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uTHlzbyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bS5MeXNvJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXy5SdW1pbm9jb2NjdXMuJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLkx5c28gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdTdW0uTHlzbycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1N1bS5MeXNvIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLkx5c28nLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdTdW0uTHlzbyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1N1bS5MeXNvJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfXycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1N1bS5MeXNvIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nU3VtLkx5c28nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19WZWlsbG9uZWxsYWNlYWUuZ19fRGlhbGlzdGVyJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnU3VtLkx5c28gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmBgYAoKTG9vcCB1bmQgUGxvdHMgS29ycmVsYXRpb24gendpc2NoZW4gTFBDL1BFLVZlcmjDpGx0bmlzIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX0xQQy5QQyA8LSBmaWx0ZXIoZ2VudXNfTEksICFpcy5uYShMUEMuUEMpKQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQy5QQyA8LSBkYXRhLmZyYW1lKCkKIAogZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgIAogICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX0xQQy5QQywgIWlzLm5hKGkpKQogICAKICAgeSA9IHRtcFssaV0KICAgCiAgIHggPSB0bXAkTFBDLlBDCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgIAogICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogICAKICAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgIAogICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRMUEMuUEMKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAgCiAgIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAgCiAgIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAgCiAgIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRMUEMuUEMKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAgCiAgIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogICAKICAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19MUEMuUEMpKzEKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfTFBDLlBDW25yb3csIkZBIl0gPSAiTFBDLlBDIgogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19MUEMuUENbbnJvdywgIkdlbnVzIl0gPSBpCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQy5QQ1tucm93LCAicC52YWx1ZSJdID0gcAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19MUEMuUENbbnJvdywgInJobyJdID0gcmhvCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQy5QQ1tucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQy5QQ1tucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19MUEMuUENbbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQy5QQ1tucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgIAogfQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQy5QQyRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfTFBDLlBDJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19MUEMuUEMkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19MUEMuUEMkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19MUEMuUEMkcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfTFBDLlBDJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiAKIHdyaXRlLnRhYmxlKCBjb3JyX3NwZWFybWFuX2dlbnVzX0xQQy5QQywgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvZ2VudXMvTFBDLlBDLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKIAoKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdMUEMuUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fT3NjaWxsb3NwaXJhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDL1BDIHNlcnVtIGxpcGlkIHJhdGlvJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nTFBDLlBDJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX0ZhZWNhbGliYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xQQy5QQyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19GYWVjYWxpYmFjdGVyaXVtJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nTFBDLlBDJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDLlBDIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0NvcHJvY29jY3VzJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nTFBDLlBDJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQWN0aW5vYmFjdGVyaWEub19fQmlmaWRvYmFjdGVyaWFsZXMuZl9fQmlmaWRvYmFjdGVyaWFjZWFlLmdfX0JpZmlkb2JhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJyxjb3IuY29lZi5jb29yZCA9IGMoMC4wMywgLTEpLCB4bGFiPSAnTFBDL1BDIHNlcnVtIGxpcGlkIHJhdGlvJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0JpZmlkb2JhY3Rlcml1bScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nTFBDLlBDJywgeT0na19fQmFjdGVyaWEucF9fUHJvdGVvYmFjdGVyaWEuY19fQmV0YXByb3Rlb2JhY3RlcmlhLm9fX0J1cmtob2xkZXJpYWxlcy5mX19BbGNhbGlnZW5hY2VhZS5nX19TdXR0ZXJlbGxhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDLlBDIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdMUEMuUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xQQy5QQyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nTFBDLlBDJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0RvcmVhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDLlBDIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RvcmVhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nTFBDLlBDJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fVmVpbGxvbmVsbGFjZWFlLmdfX0RpYWxpc3RlcicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xQQy5QQyBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0xQQy5QQycsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19QaGFzY29sYXJjdG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMUEMuUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdMUEMuUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fLlJ1bWlub2NvY2N1cy4nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMUEMuUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdMUEMuUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMUEMuUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdMUEMuUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMUEMuUEMgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdMUEMuUEMnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnTFBDLlBDIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nTFBDLlBDJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX1BvcnBoeXJvbW9uYWRhY2VhZS5nX19QYXJhYmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdMUEMvUEMgc2VydW0gbGlwaWQgcmF0aW8nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fUGFyYWJhY3Rlcm9pZGVzJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nTFBDLlBDJywgeT0na19fQmFjdGVyaWEucF9fQWN0aW5vYmFjdGVyaWEuY19fQ29yaW9iYWN0ZXJpaWEub19fQ29yaW9iYWN0ZXJpYWxlcy5mX19Db3Jpb2JhY3RlcmlhY2VhZS5nX19Db2xsaW5zZWxsYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0xQQy9QQyBzZXJ1bSBsaXBpZCByYXRpbycsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19MYWNobm9zcGlyYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAoKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBDRVIvU00tVmVyaMOkbHRuaXMgdW5kIGdlbnVzLWxldmVsCgpgYGB7cn0KIGNvcnJfbWFwX2dlbnVzX0NFUi5TTSA8LSBmaWx0ZXIoZ2VudXNfTEksICFpcy5uYShDRVIuU00pKQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX0NFUi5TTSA8LSBkYXRhLmZyYW1lKCkKIAogZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgIAogICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX0NFUi5TTSwgIWlzLm5hKGkpKQogICAKICAgeSA9IHRtcFssaV0KICAgCiAgIHggPSB0bXAkQ0VSLlNNCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgIAogICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogICAKICAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgIAogICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRDRVIuU00KICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAgCiAgIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAgCiAgIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAgCiAgIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRDRVIuU00KICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BPU1QgPC0gY29yLnRlc3QociwgcywgbWV0aG9kPSJzcGVhcm1hbiIpCiAgIAogICByaG9fUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkZXN0aW1hdGUKICAgCiAgIHBfUE9TVCA9IHRtcF9jb3JyX3NwZWFybWFuX1BPU1QkcC52YWx1ZQogICAKICAgbnJvdyA9IG5yb3coY29ycl9zcGVhcm1hbl9nZW51c19DRVIuU00pKzEKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfQ0VSLlNNW25yb3csIkZBIl0gPSAiQ0VSLlNNIgogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19DRVIuU01bbnJvdywgIkdlbnVzIl0gPSBpCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0NFUi5TTVtucm93LCAicC52YWx1ZSJdID0gcAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19DRVIuU01bbnJvdywgInJobyJdID0gcmhvCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0NFUi5TTVtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0NFUi5TTVtucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19DRVIuU01bbnJvdywgInAudmFsdWVfUE9TVCJdID0gcF9QT1NUCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX0NFUi5TTVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgIAogfQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX0NFUi5TTSRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfQ0VSLlNNJHAudmFsdWUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19DRVIuU00kcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19DRVIuU00kcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19DRVIuU00kcC5hZGp1c3RlZF9QT1NUIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfQ0VSLlNNJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiAKIHdyaXRlLnRhYmxlKCBjb3JyX3NwZWFybWFuX2dlbnVzX0NFUi5TTSwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvZ2VudXMvQ0VSLlNNLnR4dCcsIHNlcCA9Ilx0IiwgY29sLm5hbWVzID0gVFJVRSxyb3cubmFtZXMgPSBGQUxTRSkKCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nQ0VSLlNNJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0NFUi5TTSBzZXJ1bSBsaXBpZCByYXRpbycsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Pc2NpbGxvc3BpcmEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0NFUi5TTScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJyxjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdDRVIuU00gc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRmFlY2FsaWJhY3Rlcml1bScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0NFUi5TTScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Db3Byb2NvY2N1cycsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0NFUi5TTSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db3Byb2NvY2N1cycpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0NFUi5TTScsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLmNfX0JldGFwcm90ZW9iYWN0ZXJpYS5vX19CdXJraG9sZGVyaWFsZXMuZl9fQWxjYWxpZ2VuYWNlYWUuZ19fU3V0dGVyZWxsYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0NFUi5TTSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdDRVIuU00nLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0NFUi5TTSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nQ0VSLlNNJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0RvcmVhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSLlNNIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RvcmVhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdDRVIuU00nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19WZWlsbG9uZWxsYWNlYWUuZ19fRGlhbGlzdGVyJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSLlNNIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdDRVIuU00nLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19WZWlsbG9uZWxsYWNlYWUuZ19fUGhhc2NvbGFyY3RvYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSLlNNIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nQ0VSLlNNJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXy5SdW1pbm9jb2NjdXMuJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSLlNNIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nQ0VSLlNNJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0RvcmVhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSLlNNIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nQ0VSLlNNJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX0JhY3Rlcm9pZGFjZWFlLmdfX0JhY3Rlcm9pZGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSLlNNIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nQ0VSLlNNJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fQ2xvc3RyaWRpYWNlYWUuZ19fJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnQ0VSLlNNIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgoKYGBgCgpMb29wIHVuZCBQbG90cyBLb3JyZWxhdGlvbiB6d2lzY2hlbiBIZXhDZXIvQ0VSLVZlcmjDpGx0bmlzIHVuZCBnZW51cy1sZXZlbAoKYGBge3J9CmNvcnJfbWFwX2dlbnVzX0hleENlci5DRVIgPC0gZmlsdGVyKGdlbnVzX0xJLCAhaXMubmEoSGV4Q2VyLkNFUikpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfSGV4Q2VyLkNFUiA8LSBkYXRhLmZyYW1lKCkKIAogZm9yKCBpIGluIGdlbnVzX2NvbG5hbWVzKSB7CiAgIAogICB0bXAgPC0gZmlsdGVyKGNvcnJfbWFwX2dlbnVzX0hleENlci5DRVIsICFpcy5uYShpKSkKICAgCiAgIHkgPSB0bXBbLGldCiAgIAogICB4ID0gdG1wJEhleENlci5DRVIKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuIDwtIGNvci50ZXN0KHgsIHksIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvID0gdG1wX2NvcnJfc3BlYXJtYW4kZXN0aW1hdGUKICAgCiAgIHAgPSB0bXBfY29ycl9zcGVhcm1hbiRwLnZhbHVlCiAgIAogICB6ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKVssaV0KICAgCiAgIHcgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUFJFIikpJEhleENlci5DRVIKICAgCiAgIHRtcF9jb3JyX3NwZWFybWFuX1BSRSA8LSBjb3IudGVzdCh6LCB3LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJob19QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkZXN0aW1hdGUKICAgCiAgIHBfUFJFID0gdG1wX2NvcnJfc3BlYXJtYW5fUFJFJHAudmFsdWUKICAgCiAgIHIgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKVssaV0KICAgCiAgIHMgPSBzdWJzZXQoZmlsdGVyKHRtcCwgVGltZSA9PSAiUE9TVCIpKSRIZXhDZXIuQ0VSCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgIAogICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAgCiAgIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfSGV4Q2VyLkNFUikrMQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXIuQ0VSW25yb3csIkZBIl0gPSAiSGV4Q2VyLkNFUiIKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfSGV4Q2VyLkNFUltucm93LCAiR2VudXMiXSA9IGkKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfSGV4Q2VyLkNFUltucm93LCAicC52YWx1ZSJdID0gcAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXIuQ0VSW25yb3csICJyaG8iXSA9IHJobwogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXIuQ0VSW25yb3csICJwLnZhbHVlX1BSRSJdID0gcF9QUkUKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfSGV4Q2VyLkNFUltucm93LCAicmhvX1BSRSJdID0gcmhvX1BSRQogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXIuQ0VSW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXIuQ0VSW25yb3csICJyaG9fUE9TVCJdID0gcmhvX1BPU1QKICAgCiB9CiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfSGV4Q2VyLkNFUiRwLmFkanVzdGVkIDwtIHAuYWRqdXN0KGNvcnJfc3BlYXJtYW5fZ2VudXNfSGV4Q2VyLkNFUiRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfSGV4Q2VyLkNFUiRwLmFkanVzdGVkX1BSRSA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX0hleENlci5DRVIkcC52YWx1ZV9QUkUsIG1ldGhvZCA9ICJCSCIsIG4gPSAzNSkKIAogY29ycl9zcGVhcm1hbl9nZW51c19IZXhDZXIuQ0VSJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX0hleENlci5DRVIkcC52YWx1ZV9QT1NULCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIAogd3JpdGUudGFibGUoIGNvcnJfc3BlYXJtYW5fZ2VudXNfSGV4Q2VyLkNFUiwgZmlsZSA9ICcvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9zZXJ1bSBsaXBpZHMvZ2VudXMvSGV4Q2VyLkNFUi50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCiAKCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nSGV4Q2VyLkNFUicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19Pc2NpbGxvc3BpcmEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdIZXhDZXIuQ0VSIHNlcnVtIGxpcGlkIHJhdGlvJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nSGV4Q2VyLkNFUicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX19GYWVjYWxpYmFjdGVyaXVtJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJyxjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdIZXhDZXIuQ0VSIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0ZhZWNhbGliYWN0ZXJpdW0nKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCggaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdIZXhDZXIuQ0VSJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnSGV4Q2VyLkNFUiBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Db3Byb2NvY2N1cycpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0hleENlci5DRVInLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYS5jX19CZXRhcHJvdGVvYmFjdGVyaWEub19fQnVya2hvbGRlcmlhbGVzLmZfX0FsY2FsaWdlbmFjZWFlLmdfX1N1dHRlcmVsbGEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdIZXhDZXIuQ0VSIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0hleENlci5DRVInLCB5PSdrX19CYWN0ZXJpYS5wX19WZXJydWNvbWljcm9iaWEuY19fVmVycnVjb21pY3JvYmlhZS5vX19WZXJydWNvbWljcm9iaWFsZXMuZl9fVmVycnVjb21pY3JvYmlhY2VhZS5nX19Ba2tlcm1hbnNpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0hleENlci5DRVIgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fU3V0dGVyZWxsYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0hleENlci5DRVInLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdIZXhDZXIuQ0VSIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RvcmVhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nSGV4Q2VyLkNFUicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1J1bWlub2NvY2NhY2VhZS5nX18nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdIZXhDZXIuQ0VSIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nSGV4Q2VyLkNFUicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19QaGFzY29sYXJjdG9iYWN0ZXJpdW0nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdIZXhDZXIuQ0VSIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nSGV4Q2VyLkNFUicsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX18uUnVtaW5vY29jY3VzLicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0hleENlci5DRVIgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdIZXhDZXIuQ0VSJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0RvcmVhJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnSGV4Q2VyLkNFUiBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J0hleENlci5DRVInLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdIZXhDZXIuQ0VSIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdIZXhDZXIuQ0VSJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19FcnlzaXBlbG90cmljaGkub19fRXJ5c2lwZWxvdHJpY2hhbGVzLmZfX0VyeXNpcGVsb3RyaWNoYWNlYWUuZ19fLkV1YmFjdGVyaXVtLicsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ0hleENlci5DRVIgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCmBgYAoKTG9vcCB1bmQgUGxvdHMgS29ycmVsYXRpb24gendpc2NoZW4gUEMvUEUtVmVyaMOkbHRuaXMgdW5kIGdlbnVzLWxldmVsCgpJbiBBcmJlaXQKCmBgYHtyfQogY29ycl9tYXBfZ2VudXNfUEMuUEUgPC0gZmlsdGVyKGdlbnVzX0xJLCAhaXMubmEoUEMuUEUpKQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1BDLlBFIDwtIGRhdGEuZnJhbWUoKQogCiBmb3IoIGkgaW4gZ2VudXNfY29sbmFtZXMpIHsKICAgCiAgIHRtcCA8LSBmaWx0ZXIoY29ycl9tYXBfZ2VudXNfUEMuUEUsICFpcy5uYShpKSkKICAgCiAgIHkgPSB0bXBbLGldCiAgIAogICB4ID0gdG1wJFBDLlBFCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbiA8LSBjb3IudGVzdCh4LCB5LCBtZXRob2Q9InNwZWFybWFuIikKICAgCiAgIHJobyA9IHRtcF9jb3JyX3NwZWFybWFuJGVzdGltYXRlCiAgIAogICBwID0gdG1wX2NvcnJfc3BlYXJtYW4kcC52YWx1ZQogICAKICAgeiA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQUkUiKSlbLGldCiAgIAogICB3ID0gc3Vic2V0KGZpbHRlcih0bXAsIFRpbWUgPT0gIlBSRSIpKSRQQy5QRQogICAKICAgdG1wX2NvcnJfc3BlYXJtYW5fUFJFIDwtIGNvci50ZXN0KHosIHcsIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvX1BSRSA9IHRtcF9jb3JyX3NwZWFybWFuX1BSRSRlc3RpbWF0ZQogICAKICAgcF9QUkUgPSB0bXBfY29ycl9zcGVhcm1hbl9QUkUkcC52YWx1ZQogICAKICAgciA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpWyxpXQogICAKICAgcyA9IHN1YnNldChmaWx0ZXIodG1wLCBUaW1lID09ICJQT1NUIikpJFBDLlBFCiAgIAogICB0bXBfY29ycl9zcGVhcm1hbl9QT1NUIDwtIGNvci50ZXN0KHIsIHMsIG1ldGhvZD0ic3BlYXJtYW4iKQogICAKICAgcmhvX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJGVzdGltYXRlCiAgIAogICBwX1BPU1QgPSB0bXBfY29ycl9zcGVhcm1hbl9QT1NUJHAudmFsdWUKICAgCiAgIG5yb3cgPSBucm93KGNvcnJfc3BlYXJtYW5fZ2VudXNfUEMuUEUpKzEKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEMuUEVbbnJvdywiRkEiXSA9ICJQQy5QRSIKICAgCiAgIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEMuUEVbbnJvdywgIkdlbnVzIl0gPSBpCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BDLlBFW25yb3csICJwLnZhbHVlIl0gPSBwCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BDLlBFW25yb3csICJyaG8iXSA9IHJobwogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19QQy5QRVtucm93LCAicC52YWx1ZV9QUkUiXSA9IHBfUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BDLlBFW25yb3csICJyaG9fUFJFIl0gPSByaG9fUFJFCiAgIAogICBjb3JyX3NwZWFybWFuX2dlbnVzX1BDLlBFW25yb3csICJwLnZhbHVlX1BPU1QiXSA9IHBfUE9TVAogICAKICAgY29ycl9zcGVhcm1hbl9nZW51c19QQy5QRVtucm93LCAicmhvX1BPU1QiXSA9IHJob19QT1NUCiAgIAogfQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1BDLlBFJHAuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19QQy5QRSRwLnZhbHVlLCBtZXRob2QgPSAiQkgiLCBuID0gMzUpCiAKIGNvcnJfc3BlYXJtYW5fZ2VudXNfUEMuUEUkcC5hZGp1c3RlZF9QUkUgPC0gcC5hZGp1c3QoY29ycl9zcGVhcm1hbl9nZW51c19QQy5QRSRwLnZhbHVlX1BSRSwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiBjb3JyX3NwZWFybWFuX2dlbnVzX1BDLlBFJHAuYWRqdXN0ZWRfUE9TVCA8LSBwLmFkanVzdChjb3JyX3NwZWFybWFuX2dlbnVzX1BDLlBFJHAudmFsdWVfUE9TVCwgbWV0aG9kID0gIkJIIiwgbiA9IDM1KQogCiAKIHdyaXRlLnRhYmxlKCBjb3JyX3NwZWFybWFuX2dlbnVzX1BDLlBFLCBmaWxlID0gJy9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL3NlcnVtIGxpcGlkcy9nZW51cy9QQy5QRS50eHQnLCBzZXAgPSJcdCIsIGNvbC5uYW1lcyA9IFRSVUUscm93Lm5hbWVzID0gRkFMU0UpCiAKIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BDLlBFJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fUnVtaW5vY29jY2FjZWFlLmdfX09zY2lsbG9zcGlyYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDL1BFIHNlcnVtIGxpcGlkIHJhdGlvJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX09zY2lsbG9zcGlyYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEMuUEUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19SdW1pbm9jb2NjYWNlYWUuZ19fRmFlY2FsaWJhY3Rlcml1bScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEMuUEUgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRmFlY2FsaWJhY3Rlcml1bScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BDLlBFJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfX0NvcHJvY29jY3VzJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEMuUEUgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQ29wcm9jb2NjdXMnKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQQy5QRScsIHk9J2tfX0JhY3RlcmlhLnBfX1Byb3Rlb2JhY3RlcmlhLmNfX0JldGFwcm90ZW9iYWN0ZXJpYS5vX19CdXJraG9sZGVyaWFsZXMuZl9fQWxjYWxpZ2VuYWNlYWUuZ19fU3V0dGVyZWxsYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDLlBFIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX1N1dHRlcmVsbGEnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BDLlBFJywgeT0na19fQmFjdGVyaWEucF9fVmVycnVjb21pY3JvYmlhLmNfX1ZlcnJ1Y29taWNyb2JpYWUub19fVmVycnVjb21pY3JvYmlhbGVzLmZfX1ZlcnJ1Y29taWNyb2JpYWNlYWUuZ19fQWtrZXJtYW5zaWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQy5QRSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19TdXR0ZXJlbGxhJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEMuUEUnLCB5PSdrX19CYWN0ZXJpYS5wX19GaXJtaWN1dGVzLmNfX0Nsb3N0cmlkaWEub19fQ2xvc3RyaWRpYWxlcy5mX19MYWNobm9zcGlyYWNlYWUuZ19fRG9yZWEnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQy9QRSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19Eb3JlYScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQQy5QRScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX1ZlaWxsb25lbGxhY2VhZS5nX19EaWFsaXN0ZXInLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQy5QRSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BDLlBFJywgeT0na19fQmFjdGVyaWEucF9fQmFjdGVyb2lkZXRlcy5jX19CYWN0ZXJvaWRpYS5vX19CYWN0ZXJvaWRhbGVzLmZfX0JhY3Rlcm9pZGFjZWFlLmdfX0JhY3Rlcm9pZGVzJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEMvUEUgc2VydW0gbGlwaWQgcmF0aW8nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fQmFjdGVyb2lkZXMnKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIAogCiBwZGYoIi9Vc2Vycy9zdHVkZW50MDUvRG9jdW1lbnRzL2ZlcnRpZ2UgUGxvdHMvUEMuUEUuUHJvdGVvLnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQogZ2dzY2F0dGVyKHBoeWx1bV9MSSwgeD0nUEMuUEUnLCB5PSdrX19CYWN0ZXJpYS5wX19Qcm90ZW9iYWN0ZXJpYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCdza3libHVlJywgJ29yY2hpZCcpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCBjb3IuY29lZi5jb29yZCA9IGMoMzAsIC0xLjcgKSwgY29yLmNvZWYuc2l6ZSA9IDcseGxhYj0gJ1BDL1BFIFZlcmjDpGx0bmlzJywgeWxhYiA9ICdSZWxhdGl2ZXMgVm9ya29tbWVuIHBfX1Byb3Rlb2JhY3RlcmlhIFslXScpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsIHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdD0xKSkrCiAgIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCiBkZXYub2ZmKCkKIAogZ2VudXNfTEkkVGltZSA8LSBmYWN0b3IoZ2VudXNfTEkkVGltZSwgbGV2ZWxzID0gYygiUFJFIiwgIlBPU1QiKSkKIAogcGRmKCIvVXNlcnMvc3R1ZGVudDA1L0RvY3VtZW50cy9mZXJ0aWdlIFBsb3RzL1BDLlBFLmJhY3Rlcm9pZGVzLnBkZiIsd2lkdGg9OCwgaGVpZ2h0PTEwKQogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQQy5QRScsIHk9J2tfX0JhY3RlcmlhLnBfX0JhY3Rlcm9pZGV0ZXMuY19fQmFjdGVyb2lkaWEub19fQmFjdGVyb2lkYWxlcy5mX19CYWN0ZXJvaWRhY2VhZS5nX19CYWN0ZXJvaWRlcycsc2l6ZSA9IDIuNSxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3NreWJsdWUnLCAnb3JjaGlkJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIGNvci5jb2VmLmNvb3JkID0gYygzMCwgLTEpLCBjb3IuY29lZi5zaXplID0gNyx4bGFiPSAnUEMvUEUgVmVyaMOkbHRuaXMnLCB5bGFiID0gJ1JlbGF0aXZlcyBWb3Jrb21tZW4gZ19fQmFjdGVyb2lkZXMgWyVdJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSwgc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0PTEpKSsKICAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKIGRldi5vZmYoKQogCiBnZ3NjYXR0ZXIoZ2VudXNfTEksIHg9J1BDLlBFJywgeT0na19fQmFjdGVyaWEucF9fRmlybWljdXRlcy5jX19DbG9zdHJpZGlhLm9fX0Nsb3N0cmlkaWFsZXMuZl9fTGFjaG5vc3BpcmFjZWFlLmdfXy5SdW1pbm9jb2NjdXMuJyxjb2xvciA9ICdUaW1lJywgcGFsZXR0ZSA9IGMoJ3RvbWF0bycsICd5ZWxsb3dncmVlbicpLCAgYWRkID0gJ3JlZy5saW5lJywgY29uZi5pbnQgPSBUUlVFLCAKICAgICAgICAgICBjb3IuY29lZiA9IFRSVUUsIGNvci5tZXRob2QgPSAnc3BlYXJtYW4nLCB4bGFiPSAnUEMuUEUgc2VydW0gbGlwaWQgY29uY2VudHJhdGlvbiBbbm1vbC9tbF0nLCB5bGFiID0gJ2xvZzEwIChSZWxhdGl2ZSBBYnVuZGFuY2UgZ19fRGlhbHN0ZXInKSsKICAgZmFjZXRfZ3JpZCgufiBUaW1lLHNjYWxlcyA9ICJmcmVlX3giKSsKICAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIikpKwogICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpLAogICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT02MCwgaGp1c3Q9MSkpKwogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAKIAogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQQy5QRScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fQ2xvc3RyaWRpYS5vX19DbG9zdHJpZGlhbGVzLmZfX0xhY2hub3NwaXJhY2VhZS5nX19Eb3JlYScsY29sb3IgPSAnVGltZScsIHBhbGV0dGUgPSBjKCd0b21hdG8nLCAneWVsbG93Z3JlZW4nKSwgIGFkZCA9ICdyZWcubGluZScsIGNvbmYuaW50ID0gVFJVRSwgCiAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLCBjb3IubWV0aG9kID0gJ3NwZWFybWFuJywgeGxhYj0gJ1BDLlBFIHNlcnVtIGxpcGlkIGNvbmNlbnRyYXRpb24gW25tb2wvbWxdJywgeWxhYiA9ICdsb2cxMCAoUmVsYXRpdmUgQWJ1bmRhbmNlIGdfX0RpYWxzdGVyJykrCiAgIGZhY2V0X2dyaWQoLn4gVGltZSxzY2FsZXMgPSAiZnJlZV94IikrCiAgIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpKSsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEMuUEUnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQy9QRSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsY29yLmNvZWYuY29vcmQgPSBjKDMwLCAtMS4xKSwgY29yLmNvZWYuc2l6ZSA9IDYsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CYWN0ZXJvaWRlcycpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCiAKIGdnc2NhdHRlcihnZW51c19MSSwgeD0nUEMuUEUnLCB5PSdrX19CYWN0ZXJpYS5wX19CYWN0ZXJvaWRldGVzLmNfX0JhY3Rlcm9pZGlhLm9fX0JhY3Rlcm9pZGFsZXMuZl9fQmFjdGVyb2lkYWNlYWUuZ19fQmFjdGVyb2lkZXMnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQy9QRSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsY29yLmNvZWYuY29vcmQgPSBjKDMwLCAtMS4xKSwgY29yLmNvZWYuc2l6ZSA9IDYsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19CYWN0ZXJvaWRlcycpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTAsIGhqdXN0PTEpKSsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgCgogZ2dzY2F0dGVyKGdlbnVzX0xJLCB4PSdQQy5QRScsIHk9J2tfX0JhY3RlcmlhLnBfX0Zpcm1pY3V0ZXMuY19fRXJ5c2lwZWxvdHJpY2hpLm9fX0VyeXNpcGVsb3RyaWNoYWxlcy5mX19FcnlzaXBlbG90cmljaGFjZWFlLmdfXy5FdWJhY3Rlcml1bS4nLGNvbG9yID0gJ1RpbWUnLCBwYWxldHRlID0gYygndG9tYXRvJywgJ3llbGxvd2dyZWVuJyksICBhZGQgPSAncmVnLmxpbmUnLCBjb25mLmludCA9IFRSVUUsIAogICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICdzcGVhcm1hbicsIHhsYWI9ICdQQy5QRSBzZXJ1bSBsaXBpZCBjb25jZW50cmF0aW9uIFtubW9sL21sXScsIHlsYWIgPSAnbG9nMTAgKFJlbGF0aXZlIEFidW5kYW5jZSBnX19EaWFsc3RlcicpKwogICBmYWNldF9ncmlkKC5+IFRpbWUsc2NhbGVzID0gImZyZWVfeCIpKwogICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSkrCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMyksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTYwLCBoanVzdD0xKSkrCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpIApgYGAKCiAK